Is there a way to create methods just for the instance of a Ruby class from inside that instance?

You need to grab a reference to the instance's singleton class, the class that holds all the instance specific stuff, and define the method on it. In ruby 1.8, it looks a little messy. (if you find a cleaner solution let me know!)

Ruby 1.8

class Example
  def initialize(test='hey')
    singleton = class << self; self end
    singleton.send :define_method, :say_hello, lambda { test }
  end
end

Ruby 1.9 however, provides a much easier way in.

Ruby 1.9

class Example
  def initialize(test='hey')
    define_singleton_method :say_hello, lambda { test }
  end
end

First off, a small style tip:

self.class.send(:define_method, :say_hello, lambda { test })

You can make this look a little bit nicer by using the new proc literal in Ruby 1.9:

self.class.send(:define_method, :say_hello, -> { test })

But you don't need that. Ruby has something called blocks, which are basically a piece of code that you can pass as an argument to a method. In fact, you already used blocks, since lambda is just a method which takes a block as an argument and returns a Proc. However, define_method already takes a block anyway, there is no need to pass a block to lambda which converts it to a Proc which it passes to define_method which then converts it back into a block:

self.class.send(:define_method, :say_hello) { test }

As you already noticed, you are defining the method on the wrong class. You are defining it on the Example class, since inside an instance method like initialize, self is the current object (i.e. ex1 or ex2 in @mikej's example), which means that self.class is ex1's class, which is Example. So, you are overwriting the same method over and over again.

This leads to the following unwanted behavior:

ex1 = Example.new('ex1')
ex2 = Example.new('ex2') # warning: method redefined; discarding old say_hello
ex1.say_hello            # => ex2 # Huh?!?

Instead, if you want a singleton method, you need to define it on the singleton class:

(class << self; self end).send(:define_method, :say_hello) { test }

This works as intended:

ex1 = Example.new('ex1')
ex2 = Example.new('ex2')
ex1.say_hello            # => ex1
ex2.say_hello            # => ex2

In Ruby 1.9, there's a method that does that:

define_singleton_method(:say_hello) { test }

Now, this works the way you want it to, but there's a higher-level problem here: this is not Ruby code. It is Ruby syntax, but it's not Ruby code, it's Scheme.

Now, Scheme is a brilliant language and writing Scheme code in Ruby syntax is certainly not a bad thing to do. It beats the hell out of writing Java or PHP code in Ruby syntax, or, as was the case in a StackOverflow question yesterday, Fortran-57 code in Ruby syntax. But it's not as good as writing Ruby code in Ruby syntax.

Scheme is a functional language. Functional languages use functions (more precisely, function closures) for encapsulation and state. But Ruby is not a functional language, it is an object-oriented language and OO languages use objects for encapsulation and state.

So, function closures become objects and captured variables become instance variables.

We can also come at this from a completely different angle: what you are doing is that you are defining a singleton method, which is a method whose purpose it is to define behavior which is specific to one object. But you are defining that singleton method for every instance of the class, and you are defining the same singleton method for every instance of the class. We already have a mechanism for defining behavior for every instance of a class: instance methods.

Both of these arguments come from completely opposite directions, but they arrive at the same destination:

class Example
  def initialize(test='hey')
    @test = test
  end

  def say_hello
    @test
  end
end