Reputation: 1070
I'm new to ruby and trying to duplicate this perl, that calls anonymous subroutines, in ruby:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
# Make a reference to a subroutine
my $codes = {
one => sub {
say "This is code block one";
say "And this is code block one's line two"
},
};
for my $next_code ( keys %{ $codes } ) {
# Execute anonymous subroutine
&{ $codes->{ $next_code } };
}
I tried this:
#!/usr/bin/ruby -w
codes = {
one: puts "This is code block one"
puts "And this is code block one's line two",
}
codes.each do |next_code|
next_code
end
But, I get syntax errors. Is this possible, or is there another preferred ruby way?
UPDATE: Yes, this is like a dispatch table. I store code in a hash and run that code later.
Upvotes: 3
Views: 132
Reputation: 369428
Ruby has Proc
s as anonymous first-class subroutine objects. Proc
s can be created by passing a block to Proc::new
, Kernel#proc
, or Kernel#lambda
, or with the "stabby lambda" lambda literal syntax.
#!/usr/bin/env ruby
# Make a reference to a subroutine
codes = {
one: -> {
puts "This is code block one"
puts "And this is code block one's line two"
}
}
codes.each do |name, code|
# Execute anonymous subroutine
code.()
end
The most widely-used form of anonymous code block in Ruby is a construct called a block, which is actually not an object, but just a syntactic construct. Every method in Ruby takes exactly one optional block argument, which can be passed either in curly braces or using a do
/end
keyword pair after the normal method arguments. You can see a block in action in the code above, being passed to the Hash#each
iteration method.
In case you are interested, here is a small toy project of mine that demonstrates the use of first-class closures in a variety of languages, including Perl5 and Perl6, Ruby, PHP, Python, ECMAScript, Smalltalk, Clojure, Scheme, and many others: http://joergwmittag.github.io/lambdaconscarcdr/
Upvotes: 7