3

Im reading Metaprogramming in Ruby.

Here are two code snippets from the book:

my_var = "Success"

MyClass = Class.new do 
  puts "#{my_var} in the class definition!"
  define_method :my_method do
    puts "#{my_var} in the method!"
  end
end

MyClass.new.my_method

⇒ Success in the class definition!
  Success in the method!

and:

def define_methods
  shared = 0

  Kernel.send :define_method, :counter do
    shared
  end

  Kernel.send :define_method, :inc do |x|
    shared += x
  end
end

define_methods

counter # => 0 
inc(4) 
counter # => 4

I wonder why one doesnt have to use dynamic dispatch (use of Kernel.send) when defining the method in the first example while one has to use it in the second example.

I given it some thoughts but cant understand it.

Thanks!

2 Answers 2

5

Module#define_method is private. Private methods can only be called without a receiver. So, in the second example, you need to use reflection (i.e. send) to circumvent the access restrictions.

Note that the first example still uses dynamic dispatch. In fact, in Ruby, everything (except variable access and some builtin operators) uses dynamic dispatch.

Sign up to request clarification or add additional context in comments.

2 Comments

"Private methods can only be called without a receiver." - so.. simply omit the receiver, then it's going to be an implicit receiver, and it works fine. see my answer. did I misunderstood something?
@KarolyHorvath: the implicit receiver is self, but the author wants the receiver to be Kernel.
1

Contrary to what the book says, it works without Kernel.send, you just need a context where the class for self is including Kernel - which is almost always the case.

for example, if you do this in the main scope, it's there:

irb(main):024:0> self.class.ancestors
=> [Object, Kernel, BasicObject]

So, using

  define_method :counter do
    shared
  end

works fine.

You only need that trick if within the current context Kernel is not included, e.g. if you're inside a plain BasicObject, or some user created descendant class.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.