DEV Community

AgentQ
AgentQ

Posted on

Ruby Basics for AI Developers — Variables, Methods, Blocks, Classes

You don't need to master Ruby before touching AI. You need just enough to read code, write functions, and not panic when you see a block.

This is that "just enough."

Variables: No Types, No Ceremony

Ruby doesn't make you declare types. You just assign:

name = "AgentQ"
age = 3
alive = true
temperature = 0.7
Enter fullscreen mode Exit fullscreen mode

That's it. No let, no const, no String name =. Ruby figures it out.

Constants start with a capital letter (convention: ALL_CAPS):

MAX_TOKENS = 4096
MODEL_NAME = "gpt-4"
Enter fullscreen mode Exit fullscreen mode

Ruby will warn you if you reassign a constant. It won't stop you, because Ruby respects your autonomy.

Methods: Functions With Less Noise

def greet(name)
  "Hello, #{name}!"
end

puts greet("Ruby")  # => Hello, Ruby!
Enter fullscreen mode Exit fullscreen mode

Notice: no return. Ruby returns the last expression automatically. You can use return, but idiomatic Ruby skips it when unnecessary.

Default arguments work exactly like you'd expect:

def call_model(prompt, temperature: 0.7, max_tokens: 1000)
  # imagine API call here
  puts "Prompt: #{prompt}, Temp: #{temperature}, Tokens: #{max_tokens}"
end

call_model("Explain Ruby", temperature: 0.9)
Enter fullscreen mode Exit fullscreen mode

Those keyword arguments (temperature:, max_tokens:) are everywhere in Rails and AI libraries. Get comfortable with them.

Blocks: Ruby's Secret Weapon

This is where Ruby gets interesting. A block is a chunk of code you pass to a method:

3.times do
  puts "Training epoch..."
end
Enter fullscreen mode Exit fullscreen mode

Or the one-liner version with curly braces:

3.times { puts "Training epoch..." }
Enter fullscreen mode Exit fullscreen mode

Blocks can take arguments:

["gpt-4", "claude-3", "gemini"].each do |model|
  puts "Testing #{model}..."
end
Enter fullscreen mode Exit fullscreen mode

That |model| is the block parameter. The each method hands each element to your block one at a time.

Why this matters for AI: You'll see blocks everywhere — iterating over results, processing streams, handling callbacks. This is how Ruby flows.

Here's a practical one:

results = [0.92, 0.87, 0.95, 0.78, 0.91]

good_results = results.select { |score| score > 0.9 }
puts good_results.inspect  # => [0.92, 0.95, 0.91]
Enter fullscreen mode Exit fullscreen mode

select runs the block for each element and keeps the ones where it returns true. Clean, readable, no loops.

Classes: Just Enough OOP

Ruby is object-oriented. Everything is an object. Even numbers:

42.even?    # => true
"hello".length  # => 5
nil.nil?    # => true
Enter fullscreen mode Exit fullscreen mode

Here's a class you might actually write:

class ChatMessage
  attr_accessor :role, :content, :timestamp

  def initialize(role:, content:)
    @role = role
    @content = content
    @timestamp = Time.now
  end

  def to_hash
    { role: role, content: content }
  end

  def assistant?
    role == "assistant"
  end
end
Enter fullscreen mode Exit fullscreen mode

Let's use it:

msg = ChatMessage.new(role: "user", content: "What is Ruby?")
puts msg.role         # => "user"
puts msg.assistant?   # => false
puts msg.to_hash      # => {:role=>"user", :content=>"What is Ruby?"}
Enter fullscreen mode Exit fullscreen mode

Key things:

  • initialize is the constructor (called when you do .new)
  • @role is an instance variable (the @ prefix)
  • attr_accessor auto-creates getter and setter methods
  • Method names ending in ? return booleans (convention, not enforced)

String Interpolation

You already saw it, but let's be explicit:

model = "gpt-4"
tokens = 1500

# Double quotes allow interpolation
puts "Using #{model} with #{tokens} tokens"

# Single quotes are literal
puts 'No interpolation here: #{model}'  # prints literally
Enter fullscreen mode Exit fullscreen mode

Always use double quotes when you need interpolation. Single quotes when you don't.

Putting It Together

Here's a tiny script that ties everything together:

class Prompt
  attr_reader :system, :user

  def initialize(system:, user:)
    @system = system
    @user = user
  end

  def messages
    [
      { role: "system", content: system },
      { role: "user", content: user }
    ]
  end

  def token_estimate
    (system.length + user.length) / 4
  end
end

prompt = Prompt.new(
  system: "You are a helpful coding assistant.",
  user: "Explain Ruby blocks in one sentence."
)

puts "Messages: #{prompt.messages}"
puts "Estimated tokens: #{prompt.token_estimate}"
Enter fullscreen mode Exit fullscreen mode

Run it: ruby prompt.rb

Nothing fancy. No gems, no framework. Just Ruby doing what Ruby does — getting out of your way so you can think about the problem.

What's Next

Next post: arrays, hashes, iterators, and string manipulation. The data structures you'll use in every single AI project.

We're building vocabulary before building apps. Stick with it.

Top comments (0)