Since I mentioned that it's quite trivial to implement the block_given? function in Perl, here's my implementation. It shall be pretty soon, included in the new release of Rubyish.pm.

The implementation of block_given? requires Devel::Declare. Normally it's a syntax error like this:

% perl -E 'if (block_given?) { say 42 }'
syntax error at -e line 1, near "?) "
Execution of -e aborted due to compilation errors.

If you declare block_given (without the question mark) as a arg-less sub in advance, it still produces syntax error:

% perl -E 'sub block_given(); if (block_given?) { say 42 }'
syntax error at -e line 1, near "?) "
Execution of -e aborted due to compilation errors.

Normally a bare question mark in Perl programs, if not inside of a string, can mean:

  • beginning of ternary operator: a ? b : c
  • beginning of a pattern matching: $foo =~ ?foo?;, "?...?" is just like "/.../"
  • part of a variable name like $?

(I might still miss something here... please leave me a comment if you can think of anything else.)

The function of Devel::Declare here is to rewrite block_given? to simply block_given in the source code. The implementation is then just defining the function under the name block_given. The detail of block_given is just then a matter of using DB, the built-in debugger, to retrieve the value of caller arguments and test whether the last argument is a code reference.

The source code is available at http://gist.github.com/156077 , and feel free leaving me some comments here.

ps. If you find it troublesome to sign-up to my blog, simply drop me an email or find me on irc. My nickname is "gugod" on freenode and irc.perl.org.