Is 'yield self' the same as instance_eval?

后端 未结 3 435
自闭症患者
自闭症患者 2020-12-24 02:47

Is there any difference if you define Foo with instance_eval: . . .

class Foo
    def initialize(&block)
      instance_eval(&block)         


        
3条回答
  •  北海茫月
    2020-12-24 03:31

    You just can drop the self keyword

    class Foo
      def initialize
        yield if block_given?
      end
    end
    

    Update from comments

    Using yield there is a bit new to my taste, specially when used outside irb.

    However there is a big and significant difference between instance_eval approach and yield approach, check this snippet:

    class Foo
      def initialize(&block)
        instance_eval(&block) if block_given?
      end
    end
    x = Foo.new { def foo; 'foo'; end }            
    #=> #                                            
    x.foo #=> "foo"                                                        
    z = Foo.new  #=> #                                            
    z.foo #=>NoMethodError: undefined method `foo' for #
    

    Check this one as well:

    class Foo2
      def initialize
        yield if block_given?
      end
    end
    x = Foo2.new { def foo; 'foo'; end } #=> #
    x.foo #=> private method `foo' called for # (NoMethodError)
    x.send :foo => "foo"
    z = Foo.new  #=> # 
    z.send :foo => "foo"
    

    As you can see the difference is that the former one is adding a singleton method foo to the object being initialized, while the later is adding a private method to all instances of Object class.

提交回复
热议问题