DoLoveSky
DoLoveSky

Reputation: 777

Confusion with yield call to outer block

CODE-I

def sample
  x = "hi"
  puts " #{x}"
  x = yield
  puts " #{x}"
end

In the below code block {} from here => sample {"hellooo"} called yield and assigned "hellooo" to x. Looks good and as expected.

sample{'helloo'}
# >>  hi
# >>  helloo

CODE-II

o = Object.new
def o.each
  x = yield
  p x
  x = yield
  p x
  x = yield
  p x
end
e = o.to_enum # => #<Enumerator: #<Object:0x007fd1d20494e8>:each>

Why the same not happened in the below call with e.next "sample", as the p didn't printed anything?

e.next {"sample"} # => nil
e.next # => nil
# >> nil

EDIT (Here how enum#feed did the change with the help of yield?)

o = Object.new
=> #<Object:0x2299d88>
def o.each
x = yield         
p x       
x = yield
p x 
x = yield
p x 
end
=> nil
e=o.to_enum
=> #<Enumerator: #<Object:0x2299d88>:each>
e.next
=> nil
e.feed "hi"
=> nil
e.next
"hi"
=> nil

Upvotes: 1

Views: 167

Answers (1)

sepp2k
sepp2k

Reputation: 370112

next does not take a block. So if you pass it one, it simply ignores it.

It is not possible to simulate something being returned from the block when using the next method of an enumerator. When using an to_enum, the block given to the each method will always return nil except if a value has previously supplied by the feed method.

Upvotes: 1

Related Questions