Forum: Ruby Default block parameter?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mark J.Reed (Guest)
on 2006-01-05 02:54
(Received via mailing list)
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?
James G. (Guest)
on 2006-01-05 03:30
(Received via mailing list)
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
Paul L. (Guest)
on 2006-01-05 03:57
(Received via mailing list)
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
unknown (Guest)
on 2006-01-05 04:15
(Received via mailing list)
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!
http://www.manning.com/books/black
Jacob F. (Guest)
on 2006-01-05 20:57
(Received via mailing list)
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.
unknown (Guest)
on 2006-01-07 14:37
(Received via mailing list)
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!
http://www.manning.com/books/black
Mark J.Reed (Guest)
on 2006-01-07 14:37
(Received via mailing list)
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!
This topic is locked and can not be replied to.