Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change self in a block like instance_eval method do?

instance_eval method change self in its block, eg:

class D; end
d = D.new
d.instance_eval do
  puts self  # print something like #<D:0x8a6d9f4>, not 'main'!
end

If we define a method ourself(or any other methods(other than instance_eval) which takes a block), when print self, we will get 'main', which is different from instance_eval method.eg:

[1].each do |e|
  puts self  # print 'main'
end

How can i define a method(which takes a block) like instance_eval? Thanks in advance.

like image 810
gaols Avatar asked Feb 27 '12 06:02

gaols


2 Answers

You can write a method that accepts a proc argument, and then pass that as a proc argument to instance_eval.

class Foo
  def bar(&b)
    # Do something here first.
    instance_eval &b
    # Do something else here afterward, call it again, etc.
  end
end

Foo.new.bar { puts self }

Yields

#<Foo:0x100329f00>
like image 101
Steve Jorgensen Avatar answered Oct 05 '22 23:10

Steve Jorgensen


It's obvious:

class Object
  def your_method(*args, &block)
    instance_eval &block
  end
end

receiver = Object.new

receiver.your_method do
  puts self  #=> it will print the self of receiver
end
like image 36
megas Avatar answered Oct 06 '22 01:10

megas