#!/usr/bin/ruby
def test
puts "You are in the method"
yield 1
puts "You are again back to the method"
yield 2
end
test {|a| puts "You are in the block #{a}"}
####
/usr/bin/ruby -w /home/lanx/perl/ruby/yield.rb
You are in the method
You are in the block 1
You are again back to the method
You are in the block 2
##
##
sub test {
say "You are in the method";
yield 1;
say "You are again back to the method";
yield 2;
}
test b{ say "You are in the block $_[0]" };
##
##
use strict;
use warnings;
use feature qw/say/;
=pod
Block sub is basically syntactic sugar for taking an anonymous sub {}
and returning it. Blessing it with "Block" facilitates syntax checks.
=cut
sub b(&) {
my $c_block=shift;
bless $c_block, "Block";
return $c_block;
}
=pod
"yield" uses a little know trick to access the @_ of the caller. It
checks the last argument of the caller, if its a ref blessed to
"Block" and calls it with the own arguments.
Note:
Ruby allows mixing normal arguments and blocks, as long as the
block is in the last position. When using & prototypes in Perl like
in C only the first block can be passed w/o leading sub.
=cut
sub yield {
package DB;
my ($package, $filename, $line, $subroutine)=caller(1);
no warnings;
my $c_block = $DB::args[-1];
package main;
return $c_block->(@_)
if ref $c_block eq "Block";
die "$subroutine called w/o block in $filename line $line";
}
=pod
simulating the ruby test-code
=cut
sub test {
say "You are in the method";
yield 1;
say "You are again back to the method";
yield 2;
}
test b{ say "You are in the block $_[0]" };
##
##
/usr/bin/perl -w /home/lanx/perl/ruby/yield.pl
You are in the method
You are in the block 1
You are again back to the method
You are in the block 2