今日のラクダ 6章 サブルーチン,8章 リファレンス
今回はかなり重要な情報が多し。
6章 サブルーチン
6.1 p.252
&$subref(LIST) # 間接呼び出しでは&を省略できない $subref->(LIST) # (ただし間に->を置く場合を除く)
基本的には$subref->(LIST)を使いそう。
6.4 プロトタイプ p.263
プロトタイプ宣言に関して。
一番最初に逆スラッシュものはそのすぐ右の文字列から始まらなければならない
irl @> sub mykeys (\%) { my %hash = shift; return \%hash } () pirl @> mykeys("a" => "b") ERROR: Type of arg 1 to Shell::Perl::sandbox::mykeys must be hash (not constant item) at (eval 4) line 3, near ""b") " Too many arguments for Shell::Perl::sandbox::mykeys at (eval 4) line 3, near ""b") " pirl @> %hash = ("a" => "b"); ("a", "b") pirl @> mykeys(%hash); Reference found where even-sized list expected at (eval 3) line 1. { "HASH(0x185582c)" => undef }
リテラルではダメで,変数に入れてから渡す必要がある。
@と%は、残りすべての実引数を飲み込んで,リストコンテキストを要求する。
pirl @> myreverse "a", "b", "c" ("a", "b", "c") pirl @> scalar myreverse "a", "b", "c" 3
&を最初の引数として指定した場合は,無名サブルーチンのsubを省略して「間接オブジェクトスロット」にブロックだけを置くことができる
Rubyのブロック構文のようなメソッドを定義する際に用いる。mapなど。
試しにRubyのinjectのようなものを作ってみる。
sub inject(&$@) { my ($block, $init, @array) = @_; my $prev_item = $init; for my $item (@array) { $prev_item = &$block($prev_item, $item); } return $prev_item; } pirl @> inject { my ($init, $item) = @_; $init += $item; } 1, (2,3,4,5); #=> 15
6.4.1 定数関数のインライン化 p.264
その関数の結果が定数であるか,あるいは他のリファレンスを含まない,レキシカルスコープを持つスカラーであった場合,関数を呼び出す代わりにその値が使われる。
コンパイル時に結果の計算ができる関数は変数のような扱いにして関数呼び出し時にかかるオーバーヘッドをなくしますよという理解で良いかな。
7章 フォーマット
使われているところをほとんど見たことがないし,自分では使わなそうなのでざっと眺めるにとどめておく。
8章
8.2.1 逆スラッシュ演算子 p.282
リストに適用すると,各要素へのリファレンスのリストを生成してくれる。
pirl @> \qw(abc efg hij klm) (\"abc", \"efg", \"hij", \"klm")
知らなかった。
8.2.4 ハンドルへのリファレンス p.287
通常は型グロブと型グロブへのリファレンスを区別せずに使うことができるが以下の場合は例外。
- bless: 型グロブをオブジェクトにはできない
- スコープ外へ型グロブのリファレンスを返すことはできない
8.3.5 疑似ハッシュ p.294
配列のリファレンスのうち,先頭の要素がハッシュへのリファレンスとなっているもの。
見ない機能だと思ったらdeprecatedというエラーが表示された。
8.3.7 クロージャ p.302
クロージャを関数テンプレートとして使う
{ no strict 'refs'; *$hoge = sub { # ... }; }
Rubyのdefine_method(ブロック版)とほぼ同じ。
8.4 シンボリックリファレンス
ハードリファレンス以外の値をデリファレンスすると名前として扱われる。
9章 データ構造, 10章 パッケージ, 11章 モジュールまでは読んだのだけど,今日はちょっとまとめきれないのでまた明日。