第81回 高階関数を理解できないとRubyは理解できない
Rubyにはブロックというものが存在する。
array = [1,3,5,9] array.each{|i| puts i}.each{|i| print ' '; puts i*2}
結果:
1 3 5 9 2 6 10 18
このブロックは、高階関数なのである。
まつもと直伝 プログラミングのオキテ 第5回(1) | 日経 xTECH(クロステック)
eachには
{ }
と中括弧で囲むブロックを渡しているのである。
このブロックとは処理の集まりである。つまり名前のない関数と考えることができる。
そうだ無名関数だ。無名関数については、
第14回 無名関数 - bingo_nakanishiの他言語出身者のためのPerl入門
あたりで詳しく説明してきたとおり。
高階関数については、
第15回 map - bingo_nakanishiの他言語出身者のためのPerl入門
第16回 無名関数をもっと理解する - bingo_nakanishiの他言語出身者のためのPerl入門
このあたりである。
JavaScriptでこのeachを実装したければ次のようなソースを書く。
無名関数を作りだせる言語なので、このような芸当が可能なのだ。
Array.prototype.each = function(code){ for(i=0; i<this.length; i++){ code(this[i]); } return this; } var array = [1,3,5,9]; array.each(function(i){ alert(i) }) .each(function(i){ alert(' ' + i*2) });
Perlならば、
use strict; package Array; sub new { my ($self, $list) = @_; my $class = ref $self || $self; bless $list, $class; } sub each { my $self = shift; my $code = shift; for(@$self){ $code->($_); } return $self; } package main; my $arry = Array->new([1,3,5,9]); $arry->each( sub{ print $_[0], "\n" } ) ->each( sub{ print ' ', $_[0]*2, "\n" } );
結果:
1 3 5 9 2 6 10 18
といったところだろうか。
以下は作成中の疑問....
http://perl-mongers.org/2009/01/re_map.html
を参考に、
sub each ($&) { my $self = shift; my $code = shift; for(@$self){ $code->($_); } return $self; }
で、
$arry->each{ print $_[0], "\n" } ->each{ print ' ', $_[0]*2, "\n" };
と、したかったのだが、文法エラーになってしまった.....