13

Could anyone please help me to understand the difference between "yield self" and "yield"?

class YieldFirstLast
    attr_accessor :first, :last

    def initialize(first = nil, last = nil)
        @first = first
        @last = last
        yield self if block_given?
    end

    def hello
        puts "#{@first} #{@last} says hello!"
    end
end
lighter
  • 2,808
  • 3
  • 40
  • 59
vivek kumar
  • 179
  • 3
  • 8

3 Answers3

21

In the case of yield self, self is the argument passed to the block. With simply yield, no argument is passed. self is not special here, anything could be yielded, e.g.

class Foo
  def a() yield self end
  def b() yield end
  def c() yield "Bar" end
  def d() yield 1, 2, "scuba" end
  def to_s() "A!" end
end

Foo.new.a {|x| puts x } #=> A!
Foo.new.b {|x| puts x } #=> (a blank line, nil was yielded)
Foo.new.c {|x| puts x } #=> Bar
Foo.new.d {|x, y, z| puts z } #=> scuba
numbers1311407
  • 33,686
  • 9
  • 90
  • 92
  • what if there is more than one argument passed to the block? Is Self an array of them ? – oldergod Aug 20 '12 at 05:37
  • 2
    `self` is a reference to the instance, but like I said, nothing special here. Essentially think of yield as a method that takes any arguments and passes them to the block. See the edit for multiple arguments. – numbers1311407 Aug 20 '12 at 14:12
  • Thanks for this explanation. Let me check my understanding, so when we use self, x is assigned as current objects reference. But if we don't use self, x is not assigned to any object. – vivek kumar Aug 21 '12 at 04:13
  • Yes, it might be helpful to think the block as a method, and `yield` as the invocation of that method. The block `{|x, y| x + y }` is analagous to `def fn(x, y) x + y end`. If you invoked `fn` with no arguments, `fn()`, you would expect `x` to be undefined in the method body, yes? – numbers1311407 Aug 21 '12 at 17:04
5

yield self enters block, associated with method call, passing current object as argument to the block, plain yield just enters the block without passing any arguments.

Victor Deryagin
  • 11,895
  • 1
  • 29
  • 38
2

Think of yield as invoking your block and yield self is invoking your block with the current instance as the parameter.

Aldee
  • 4,439
  • 10
  • 48
  • 71