読者です 読者をやめる 読者になる 読者になる

無名関数を引数にとる関数

perl ruby
#!/usr/bin/perl

use strict;
use warnings;
use feature qw( say );

sub hoge(&) {
  my ($func) = @_;
  $func->();
}

hoge { say 'call from anonymous function!' }

Perlを書きはじめている。なにもかもがわからない(なにがわからないのかすら、わからない)ので、いろいろとRubyでよくやることを徐々に試してみることにする。

Rubyにはブロックという概念があるんだけど、これの文法のわかりやすさも手伝って、無名関数というものへの理解が進んだとおもっている。Rubyには感謝しなくちゃいけない。

で、Perlでも同じようなことを書くには、先に出したコードを書けばよいらしい。

なるほど、これができるとPerlとRubyの違いがそんなに多くないかも、とおもわせてくれる。これはいい。

Rubyは関数(便宜上。実際はすべてメソッド)の引数としてブロック(無名関数)を渡せる。文字列や数値といったものといっしょに、引数として渡せる。

#!/usr/bin/ruby

def hoge(name, &block)
  puts name
  yield
end

hoge 'myfunc' do puts 'yeahhhhh' end

このようなことをPerlでもやりたい。

#!/usr/bin/perl

use strict;
use warnings;
use feature qw( say );

sub fuga {
  my ($name, $func) = @_;
  say $name;
  $func->();
}

fuga 'myfunc', { say 'yes!!!'; }

# $ perl closure.pl
# yes!!!
# Odd number of elements in anonymous hash at closure.pl line 13.
# myfunc
# Not a CODE reference at closure.pl line 10.

closure.pl というファイルで保存して実行してみるとこんなかんじ。ハッシュだと勘違いして怒られているっぽい。

fuga 'myfunc', sub { say 'yes!!! }

# $ perl closure.pl
# myfunc
# yes!!!

こうすると期待した動作になる。subつければいいだけっぽいんだけど、かなりダサい。こまった。