Can a lambda or Proc object yield a value to a block?

I’ve searched quite a bit on the web and through “Programming Ruby - the
Pragmatic Programmer’s Guide” and I can’t find a satisfactory answer to
the question:

Can a lambda or Proc object yield a value to a block?

For example when I try this
yieldArg = lambda {|arg| yield arg}
yieldArg.call(23) {|y| puts(“y=”+y.to_s)}
in Interactive Ruby I get
“LocalJumpError: no block given”

So I try
yieldArg = lambda {|arg| puts “no block given” unless block_given? ;
yield arg}
to print some indication of whether the block really has been “given”
and I get
no block given
LocalJumpError: no block given

So then I try to wrap the block in a lambda and pass it as a param
putsY = lambda {|y| puts(“y=”+y.to_s)}
yieldArg.call(23) {|y| puts(“y=”+y.to_s)}
yieldArg.call(23, &putsY)
but with the same negative result.

So can a lambda or Proc object yield a value to a block? If so, how is
it done?

Thanks in advance.

Interactive Ruby session shown below.

irb(main):001:0> yieldArg = lambda {|arg| yield arg}
=> #Proc:0x02dfebf0@:1(irb)
irb(main):002:0> yieldArg.call(23) {|y| puts(“y=”+y.to_s)}
LocalJumpError: no block given
from (irb):1
from (irb):2:in call' from (irb):2 irb(main):003:0> yieldArg = lambda {|arg| puts "no block given" unless block_given? ; yield arg} => #<Proc:0x02df58e8@(irb):3> irb(main):004:0> yieldArg.call(23) {|y| puts("y="+y.to_s)} no block given LocalJumpError: no block given from (irb):3 from (irb):4:incall’
from (irb):4
irb(main):005:0> putsY = lambda {|y| puts(“y=”+y.to_s)}
=> #Proc:0x02dede2c@:5(irb)
irb(main):006:0> yieldArg.call(23, &putsY)
no block given
LocalJumpError: no block given
from (irb):3
from (irb):6:in `call’
from (irb):6
irb(main):007:0>

On 8/13/07, Mick M. [email protected] wrote:

I’ve searched quite a bit on the web and through “Programming Ruby - the
Pragmatic Programmer’s Guide” and I can’t find a satisfactory answer to
the question:

Can a lambda or Proc object yield a value to a block?

Short answer, no, not yet. (You can in 1.9 by using the & syntax)

You actually can use yield in a block, you just need to realize it’s the
yield of the enclosing scope:

def example
a_proc = lambda { yield “Hi” }

if block_given?
a_proc.call
end
end

example { |x| puts x }

On Aug 13, 9:11 pm, Mick M. [email protected]
wrote:

I’ve searched quite a bit on the web and through “Programming Ruby - the
Pragmatic Programmer’s Guide” and I can’t find a satisfactory answer to
the question:

Can a lambda or Proc object yield a value to a block?

This thread from June might be helpful:

http://groups.google.com/group/comp.lang.ruby/browse_frm/thread/e2969b7038082526/b111c94a1ad32081?#b111c94a1ad32081

I learned that apparently ruby1.9 adds a lambda {|&b| … } facility.

Logan C. wrote:

You actually can use yield in a block, you just need to realize it’s the
yield of the enclosing scope:

def example
a_proc = lambda { yield “Hi” }

if block_given?
a_proc.call
end
end

example { |x| puts x }

Thanks for the reply Logan. Obviously I’ll have to study Ruby’s scope
rules a bit more. I notice that I can’t modify your example as follows
to pass in a lambda object because I get the “LocalJumpError: no block
given” error again.

a_proc = lambda { yield “Hi” }

def example2(proc)

if block_given?
proc.call
end
end

example2(a_proc) { |x| puts x }

Presumably the enclosing scope for the lambda object in my example is
outside the scope of the example2 method. It’s scope is the scope in
which it was defined which is “nowhere” really i.e. it’s outside a
class, module and method.
Presumably because of this it just can’t yield a value. Does this sound
plausible at all?

P.S. What I’m really trying to do is emulate some of things that I’ve
done before in Scheme.

For example a generic “each” maker which doesn’t work 'cos of the whole
LocalJumpError thing.

def makeEach(nextValue, start, stop)
lambda do
x = start
while x <= stop
yield x
x = nextValue.call(x)
end
end
end

from11to20 = makeEach(lambda {|x| x+1}, 11, 20)

from11to20 {|x| puts x*x}

On 8/14/07, Cleasai B. [email protected] wrote:

end

outside the scope of the example2 method. It’s scope is the scope in
which it was defined which is “nowhere” really i.e. it’s outside a
class, module and method.
Presumably because of this it just can’t yield a value. Does this sound
plausible at all?

P.S. What I’m really trying to do is emulate some of things that I’ve
done before in Scheme.

For example a generic “each” maker which doesn’t work 'cos of the whole
LocalJumpError thing.

class Stepper
def initialize(next_value, start, stop)
@next_value = next_value
@start = start
@stop = stop
end

def each
x = @start
while x <= @stop
yield x
x = @next_value.call(x)
end
end
end

from11to20 = Stepper.new(lambda { |x| x + 1}, 11, 20)
from11to20.each { |x| puts x * x }

def makeEach(nextValue, start, stop)

from11to20 {|x| puts x*x}

Even if blocks could yield, you’d still have to say
from11to20.call { |x| puts x * x }

Ruby is a Lisp-2 (like CL), you have to (funcall your lambdas

That said, if I really wanted to go from 11 to 20 I’d do

11.upto(20) { |x| puts x * x }

or 11.step(20, 1) { |x| puts x * x }