• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
変数、リファレンス
 

変数、リファレンス

on

  • 3,328 views

Hokkaido.pm #4

Hokkaido.pm #4

Statistics

Views

Total Views
3,328
Views on SlideShare
1,903
Embed Views
1,425

Actions

Likes
1
Downloads
0
Comments
0

4 Embeds 1,425

http://hokkaido.pm.org 1324
http://d.hatena.ne.jp 94
http://localhost 4
http://s.deeeki.com 3

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    変数、リファレンス 変数、リファレンス Presentation Transcript

    • 変数、リファレンス February 19, 2011 Hokkaido.pm #4 Kenichi Ishigaki (charsbar)
    • 始める前に…
    • Perl の変数なんて 別にむずかしくないよね という方?
    • 『言語設計者たちが考えること』
    • Larry がこんなことを 言っていました
    • 「自然言語の原理を コンピュータ言語へと 組み込む最善の 方法を探求」
    • Perl はもともと C 、 sed 、 awk 、 sh の よいとこどりをした言語
    • 英語っぽさを 感じることもあります
    • たとえば 英語の名詞
    • 無冠詞 : pen 単数 : a pen 複数 : pens
    • 無冠詞 (pen)   「~というもの」
    • そのままでは 数えられないもの   # または数えないもの
    • 辞書の見出し語   固有名詞 抽象名詞
    • Perl の場合
    • foo   裸のワード # 英数字と下線だけからなる単語
    • 昔はよくこんな使い方を していたものです   open FOO, 'bar';
    • 定数を定義するときにも よく使われています   use constant PI => 3.14; print PI * 2; # 6.28
    • 具体的なものの 代入は不可   foo = 'bar'; # エラー
    • 具体的なものを 扱うにはどうするか
    • そのものが 単数か複数かで 変わります
    • 単数の場合
    • 英語では冠詞を つけるのでした   pen -> a pen
    • Perl の場合は 「 $ 」という記号を つけます   foo -> $foo
    • この記号は あくまでも 冠詞扱い   # 変数名の一部ではありません
    • だからこんな 書き方も可能です   $ foo = 1; print $ foo; # 1
    • 真似しないで くださいね
    • どうして $ なのか
    • スカラー (scalar) の 頭文字   # 高校の物理で習いましたよね # 「矢印」がつかない値
    • 複数の場合
    • 英語では語形が 変わったり   a pen -> pens a man -> men
    • 数をあらわす 形容詞句がついたり   two pens a lot of men
    • 単複同型というのも ありました   単数 : a sheep 複数 : sheep
    • Perl の場合は @ という 記号をつけます   @foo = (1, 2, 3);
    • 配列 (array) の 頭文字から perldata では「 these とか those 」
    • 細かくいうと 配列とリストは別物
    • $foo と @foo の関係
    • 名前は同じです
    • いっぺんに扱う 手段もあります
    • 中身は別物です   a pen ≠ pens
    • 「複数」の性質
    • 単数+単数=複数   @pens = ($red_pen, $blue_pen);
    • 複数+複数=複数   @pens = (@red_pens, @blue_pens);
    • 要素の個数は あまり気にしません   # 複数は複数です
    • 配列の要素を 扱うときは for などで   foreach (@pens){ print $_ }   # $_ は英語の it と同じ単数の代名詞 # 中身については空気を読んで
    • コアレベルでは 省略できることも多い   foreach (@pens) { print } print for @pens;
    • 他動詞だから目的語をとるはず、というのが 暗黙の了解
    • 誤解を避けたければ 明示して   for $pen (@pens) { print $pen }
    • 処理の順番は?
    • リストの場合は左から右 ということになっています   print for (1, 2, 3);
    • でも、左ってどこ?   print for @pens;
    • どこかにはあるはずです が、隠れています
    • という記号をつけると 起点の位置を 取得できます   @pens;
    • 具体的にどこにあるかは 気にしなくていいです
    • @ という具体的な 文脈をあらわす記号を 打ち消しているイメージ
    • 起点がわかったら 向きと長さを指定すれば 個々の要素に アクセスできます   (@pens)->[0];
    • この起点のことを Perl の文脈では リファレンスと呼びます
    • 「よく使われる表現は、 あまり使われない表現 よりも短くあるべき」 ( 『言語設計者たちが考えること』 )
    • ふだんはもう少し 楽をしたいですよね
    • ひと頃は こんな風にも 書けました   @pens->[0];
    • Perl 5.8 で 廃止されました # 文脈がわかりづらくなるから # 複数のものから矢印 ?!
    • 起点はひとつしか ありません
    • ということは 単数扱いに なるはずです
    • Perl 5 では スカラーとしても 扱えるようになりました   $pens_ref = @pens; $pens_ref->[0];
    • 矢印が生えるのに !?
    • 普通のスカラーとは 違います
    • 中身を覗いて みましょう   perl -e "print @array" # ARRAY(0x33e288)
    • ぐちゃぐちゃに ならないよう 内部的には別扱い されています
    • Devel::Peek を使うと 詳しく調べられます   perl -MDevel::Peek -e "@a = (1, 2); print Dump(@a)" # Perl 5.6 以降はコアに入っています
    • むずかしいことは 忘れてください
    • 矢印が生えていれば (たいていは) リファレンスです   $pens_ref->[0];
    • ref でも確認できます   ref $scalar_or_ref ? 'ref' : 'scalar';
    • 誤解されそうな文脈では 名前を変えておきましょう   ○ $pens_ref = @pens; × $pens = @pens;
    • これでだいぶきれいに 書けるようになりました
    • でも、もう少し 楽をしたいです
    • できるように なっています   @pens; # $pens_ref = @pens; $pens[0]; # $pens_ref->[0];
    • $pens と $pens[0] と $pens->[0] は それぞれ文脈が 異なります
    • $pens は純然たるスカラー(たぶん) $pens->[0] の $pens はリファレンス $pens[0] は @pens の一要素
    • ベクトルの指す値は 矢印ひとつにつき ひとつのみです   $array_ref->[0] # 返り値はひとつのはずです
    • 配列にはスカラー (として扱えるもの) しか入れられない という制約が   $array_ref->[0] にわざわざ $ をつける必要はありません
    • 配列にはスカラー (として扱えるもの) しか入れられない という制約が   $array_ref->[0] にわざわざ $ をつける必要はありません
    • 配列から複数の値を 取り出したい場合も あります
    • ひとつひとつ列挙 してもかまいません   $first_pen = $pens[0]; $second_pen = $pens[1];   # 冗長ですよね
    • 一行にまとめてみました   ($first_pen, $second_pen) = ($pens[0], $pens[1]);
    • もう少し短くできます   ($first_pen, $second_pen) = pens; # 3 つめ以降の pen は無視されます
    • こんな書き方も できるのですが…   @two_pens = @pens[0, 1]; # @pens[0..1]
    • 必要がなければ 避けた方が無難
    • 意図とは異なる (かもしれない) 結果になるもの
    • 1 本なのに 複数扱い !? × @pens[0];
    • ベクトルの行き先はひとつのみです × $pens_ref->[0, 1]
    • 先にデリファレンスされて しまいますので… × @$pens_ref->[0, 1]
    • 配列にしてからなら OK ○ @$pens_ref[0, 1]
    • 便利に使える 場合もあります
    • 複数の配列を含む配列の場合
    • 赤だけ、青だけの 配列を区別できません   @pens = (@red_pens, @blue_pens); × (@red_pens, @blue_pens) = @pens;
    • 配列に入れられるのは スカラー扱いできる値のみ   配列をそのまま配列に 入れることはできません
    • 区別するには リファレンスを 使います   @pens = (@red_pens, @blue_pens);
    • 矢印をたどっていけば 目的地につきます   ($red_pens_ref, $blue_pens_ref) = @pens; $red_pen = $red_pens_ref->[0]; $blue_pen = $pens[1]->[0]; # = $pens[1][0];
    • 配列のなかの リファレンスから 生える矢印はふつう省略できます
    • 自動的にふられる 番号ではわかりづらい場合もあります   @pens = (@red_pens, @blue_pens);
    • 青ペンの 1 本目 には見えません ! $pens[1][0];
    • 要素が増減したら いちいち順番を直す必要があります
    • もっと明確に書きたいときは ハッシュという特殊な配列を使います   # 昔は連想配列と言っていました
    • ハッシュの場合は 届け先を明記します %pens = ( red_pens => @red_pens, blue_pens => @blue_pens, );
    • % -> c/o -> care of 「~様方」
    • 使い方は ふつうの配列と よく似ています
    • %pens = (...); $pens{red_pens}; $ pens {blue_pens};
    • $pens_ref = %pens; $pens_ref->{red_pens}; $ pens_ref -> {blue_pens};
    • それぞれの要素に アクセスしたいとき   for (keys %hash){ print $hash{$_} } for (values %hash){ print $_ } while(($key, $value) = each %hash) { ... } # 並び順は不定です
    • %pens = ( red_pens => @red_pens, blue_pens => @blue_pens, ); ハッシュのなかの 配列に名前は必要?
    • %pens = ( red_pens => ['mine', 'yours'], # @red_pens blue_pens => ['his', 'hers'], # @blue_pens ); $red_pens_ref = $pens{red_pens}; 必要なければ 省略してしまいましょう
    • [...] は無名配列の リファレンスです   (...) だと別の意味になるので要注意
    • ふつうの配列に したいときは 「冠詞」をつけて   @pens = @{['red_pen', 'blue_pen']};
    • もちろん 無名ハッシュへの リファレンスも つくれます   $pens_ref = { red_pens => 2, blue_pens => 3 }; %pens = %{{red_pen => 1, blue_pen => 2}};
    • どうして @{...} に なるのでしょう?
    • Perl にはシンボル テーブルと呼ばれる 特殊なハッシュが 用意されています
    • 中身を覗いて みましょう perl -MDevel::Symdump –e "print Devel::Symdump->rnew->as_string"
    • もう少し詳しく 見たいときはこちら   perl -MData::Dump=dump -e "print dump(%::)"
    • グローバル変数 パッケージ 関数/メソッド
    • 多くのものがこの 無名ハッシュのなかに 登録されています
    • $bl{HASH}{"Data::"}{HASH}{"Dump::"}{HASH}{"seen"} = { "16258dc" => ["k", []], "16258e8" => ["bl", ["*{HASH}"]], "1625900" => ["bl", []], "1625918" => ["al", []], } 変数名やリファレンスの ID は ハッシュのキーになっています
    • これまで見た変数は このようにも 書き換えられます
    • print ${foo}; # $foo print @{"bar"}; # @bar print ${ 'b' . 'az' }{foo}; # $baz{foo}
    • 文字列のなかに 変数を埋め込むときに便利なことも   $foo = "chars"; print "${foo}bar";
    • デリファレンスの 優先順位を明示したいときにも有効
    • 全部ひっくるめた 型グロブというものも あります   *{"foo"}
    • 昔はファイルハンドルの 受け渡しなどに 使っていました
    • いまはシンボルテーブルを いじるときにしか使いません
    • 型グロブは 「無冠詞」の変数も うまくさばいてくれます   open FOO, ‘file’; do_something(*FOO); # Perl 4 風
    • ゆるい世界では こんな書き方さえ できます
    • @array = (1, 2); print array->[0]; # 警告つき print *array->[0]; # 警告すらでません
    • 今日はあえて ゆるい世界の話に 終始しました   今日取り上げた例のいくつかは、 use strict; するとエラーになります
    • 後付けの説明なので 実際の歴史や実装とも ずれがあります
    • Perl 自体、当初の デザインからは さまざまな点で 変わってきています
    • そのすべてを覚えて いられる人は おそらくいません
    • 詳しいことを 知りたい人は perldoc.jp へ
    • perldata, perldsc, perlref, perlreftut, perlobj, perllol, perlsub, perlfaq4, perlfaq7
    • ご静聴ありがとう ございました