Default block parameter?


#1

Okay, this is probably a dumb question, but how do I declare an
optional block parameter with a default value?

I tried several variations on this basic theme:

    def meth(&block = lambda { |i| ... })
    ...
    end

But I keep getting syntax errors. Help?


#2

On Jan 4, 2006, at 6:52 PM, Mark J.Reed wrote:

Okay, this is probably a dumb question, but how do I declare an
optional block parameter with a default value?

I tried several variations on this basic theme:

    def meth(&block = lambda { |i| ... })
    ...
    end

But I keep getting syntax errors. Help?

Hopefully this will give you some ideas:

def default
if block_given?
yield
else
?> lambda { puts “Default block” }.call

end
end
=> nil

default
Default block
=> nil

default { p 2 + 2 }
4
=> nil

James Edward G. II


#3

Mark J.Reed wrote:

I think the & is your problem. You can do something like:

def foo(block = lambda {|i| puts i})
block.call(“Hi”)
end

foo()
foo(lambda {|i| puts i; puts i})

Best,
Paul


#4

Hi –

On Thu, 5 Jan 2006, Mark J.Reed wrote:

Okay, this is probably a dumb question, but how do I declare an
optional block parameter with a default value?

I tried several variations on this basic theme:

   def meth(&block = lambda { |i| ... })
   ...
   end

But I keep getting syntax errors. Help?

The &block thing is a special dispensation from Ruby, letting you grab
the block but not serving as a normal argument. The way I’ve always
seen this done is:

def meth(&block)
block ||= lambda { … }

end

I don’t think there’s a way to do it inside the arglist.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!


#5

On 1/4/06, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

The &block thing is a special dispensation from Ruby, letting you grab
the block but not serving as a normal argument. The way I’ve always
seen this done is:

def meth(&block)
block ||= lambda { … }

end

But keep in mind that assigning to block inside the method doesn’t
affect the behavior of yield:

irb> def test(&block)
irb> block ||= lambda{ puts “default” }
irb> yield
irb> end
=> nil
irb> test
LocalJumpError: no block given

So if you need a default block and currently use yield, you’ll either
need to branch on block_given? (as suggested by James), or just use
block.call instead of yield. The latter is probably preferrable, but
may have subtle differences in parameter assignment if it matters.

Jacob F.


#6

Thanks to all who posted. The upshot seems to be that I need to declare
the method with no block in the signature, and then check block_given?
within the body and manually invoke a default block if none was passed
in.

Which is basically the solution I arrived at, although I had forgotten
about
block_given? and was trapping the LocalJumpError to achieve the same
result.

Thanks again!


#7

Hi –

On Fri, 6 Jan 2006, Jacob F. wrote:

   end

But keep in mind that assigning to block inside the method doesn’t
affect the behavior of yield:

irb> def test(&block)
irb> block ||= lambda{ puts “default” }
irb> yield
irb> end
=> nil
irb> test
LocalJumpError: no block given

Right – all that happens in my version is assignment to a variable.

David


David A. Black
removed_email_address@domain.invalid

“Ruby for Rails”, from Manning Publications, coming April 2006!