Adjusting the Scope of Blocks

svg% cat b.rb
#!/usr/bin/ruby

class A
def self.n
puts “A::n”
end
end

def n
puts “Object#n”
end

A.class_eval { n }
svg%

svg% b.rb
A::n
svg%

Also

A.instance_eval { n } # => “A::n”

So what’s the difference between class_eval and instance_eval for a class?

···


– Jim Weirich / Compuware
– FWP Capture Services
– Phone: 859-386-8855

Weirich, James wrote:

So what’s the difference between class_eval and instance_eval for a class?

class A; end

A.instance_eval { def foo; “FOO”; end }

p A.foo # ==> “FOO”

class B; end

B.class_eval { def foo; “FOO”; end }

p B.new.foo # ==> “FOO”

Joel VanderWerf wrote:

Weirich, James wrote:

So what’s the difference between class_eval and instance_eval for a
class?

class A; end

A.instance_eval { def foo; “FOO”; end }

p A.foo # ==> “FOO”

class B; end

B.class_eval { def foo; “FOO”; end }

p B.new.foo # ==> “FOO”

Now, what I’ve never understood is how to detect the difference from
within the block. In other words, how could I write a method
Object#find_def_target which would behave as follows:

class A; end

A.instance_eval { find_def_target } == (class << A; self; end) # ==> true

class B; end

B.class_eval { find_def_target } == B # ==> true

That state must be somewhere in the interpreter. It it exposed somehow?
I did need this once, but I don’t remember why…