Perlには無いRubyのyield文に少し嫉妬を覚えた
最近Rubyを勉強していて、今日yield文というのに出会った。
忘れないようにメモ
yield文はこんな感じで書く
def foo ( name ) yield('おはよう' + name) yield('おやすみ' + name) end foo( 'sasakure' ) do | message | puts message end
結果はこのように表示される
おはようsasakure おやすみsasakure
fooというメソッドの中でyieldが実行されるたびに、
呼び出し元の後ろに書かれたdoブロックが実行される。
最初にこれ見た時は、
yieldが呼ばれる度に、doブロックを実行する処理が溜まっていって、
fooメソッドが終わった後で順番に実行されるのか、、、とか思ってたけど違った。
fooメソッドの中から、doブロックに飛び出してきて、
またfooメソッドの中に戻って、またdoブロックに飛び出してくる。
なにこれ新しい!!!(すくなくとも僕にとっては)
Perlで書くとこんな感じの動きですね
sub foo { my ($name, $cb, ) = @_; $cb->('おはよう' . $name); $cb->('おやすみ' . $name); } foo( 'sasakure', sub{ print shift . "\n"; } );
渡した無名関数がyieldした時に呼ばれるみたいな
それと!
yield文を調べる事で、初めてdoブロックについてもちゃんと理解できた。
Perlでブロックっていうと{}この範囲を指すけど、
Rubyでは do 〜 endを指す
※ただしdo endは {}に置き換えられるよ
んで、このdoブロックはperlと違って、単体では書けない。
必ずメソッドの後ろにくっついて宣言される。
そして、ブロック内が実行されるのは、その前のメソッド内でyieldが呼ばれた時になる。
配列のeacheメソッドも中でyield呼んでるって理解してもいいのかな?
list = [0,1,2,3] list.each do | num | puts num end
このyield文、覚えてしまうとなかなか便利かもしれない。
ちょっとPerlでも書きたくなるなぁ
Bundlerを使ってRailsをいれてみた
前回のエントリーでrubyをインストールしたので、
次はBundlerを使ってRailsを入れてみたいと思います。
やることは大きく3つ
• ruby本体にgemでBundlerを入れる
• 一時的なgemでRailsを入れる
• Railsアプリケーションを作成したら一時的なgemを消す
(その他のgemはRailsの中で管理する)
これでBundler意外のgemはアプリケーション単位でしか依存しなくなります。
※注 Ruby超初心者なので大きな誤解をしている場合がございます。
まずはgemをアップデート
$ gem update --system
そしてbundlerのインストール
$ gem install bundler Fetching: bundler-1.3.5.gem (100%) Successfully installed bundler-1.3.5 Parsing documentation for bundler-1.3.5 Installing ri documentation for bundler-1.3.5 1 gem installed $ rbenv rehash
rehashするのを忘れずに
僕はrbenvでRuby2.0.0を選択していたので、ちゃんと意図したとこに入ってるか確認
$ gem which bundler /Users/sasakure/.rbenv/versions/2.0.0-p0/lib/ruby/gems/2.0.0/gems/bundler-1.3.5/lib/bundler.rb
うん大丈夫
それではRailsを入れます。
Gemfileというファイルを「Railsをインストールするためだけに」作る必要があります。
このGemfileというのはBundlerがインストールするためのgemファイルを指定するもので、
これからRailsをインストールしたい場所に作成する必要があります。
$ cd $ mkdir RailsApps $ cd RailsApps $ vi Gemfile
Gemfileの中身はこんな感じ
source 'http://rubygems.org' gem 'rails', '3.2.13'
んで、この例でいうとRailsAppsディレクトリにいる状態で
bundle install コマンドでインストールするんですが、
オプションで--path vendor/bundleを指定するのを忘れずに!
$ bundle install --path vendor/bundle Fetching gem metadata from http://rubygems.org/........... Fetching gem metadata from http://rubygems.org/.. Resolving dependencies... Installing rake (10.0.4) Installing i18n (0.6.1) Installing multi_json (1.7.2) Installing activesupport (3.2.13) Installing builder (3.0.4) Installing activemodel (3.2.13) Installing erubis (2.7.0) Installing journey (1.0.4) Installing rack (1.4.5) Installing rack-cache (1.2) Installing rack-test (0.6.2) Installing hike (1.2.2) Installing tilt (1.3.7) Installing sprockets (2.2.2) Installing actionpack (3.2.13) Installing mime-types (1.23) Installing polyglot (0.3.3) Installing treetop (1.4.12) Installing mail (2.5.3) Installing actionmailer (3.2.13) Installing arel (3.0.2) Installing tzinfo (0.3.37) Installing activerecord (3.2.13) Installing activeresource (3.2.13) Using bundler (1.3.5) Using json (1.7.7) Installing rack-ssl (1.3.3) Installing rdoc (3.12.2) Installing thor (0.18.1) Installing railties (3.2.13) Installing rails (3.2.13) Your bundle is complete! It was installed into ./vendor/bundle Post-install message from rdoc: Depending on your version of ruby, you may need to install ruby rdoc/ri data: <= 1.8.6 : unsupported = 1.8.7 : gem install rdoc-data; rdoc-data --install = 1.9.1 : gem install rdoc-data; rdoc-data --install >= 1.9.2 : nothing to do! Yay!
ここまで良い感じ。
最後に出て来たメッセージは何だろう。
「Rubyのバージョンによってはrdocをインストールする必要があるけど、1.9.2以上なら関係ないよヒャッホー!」 ってとこかな。
あとはRailsでアプリケーションを作成したらGemfileを消せばいいんですって。
「demo」という名のアプリを作る場合は下記のようなコマンドを叩く。
※ --skip-bundleオプションでbundel installが走らないようにしておくことが重要
$ bundle exec rails new demo --skip-bundle create create README.rdoc create Rakefile create config.ru create .gitignore create Gemfile create app create app/assets/images/rails.png create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/views/layouts/application.html.erb create app/mailers/.gitkeep create app/models/.gitkeep create config create config/routes.rb create config/application.rb create config/environment.rb create config/environments create config/environments/development.rb create config/environments/production.rb create config/environments/test.rb create config/initializers create config/initializers/backtrace_silencers.rb create config/initializers/inflections.rb create config/initializers/mime_types.rb create config/initializers/secret_token.rb create config/initializers/session_store.rb create config/initializers/wrap_parameters.rb create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create doc create doc/README_FOR_APP create lib create lib/tasks create lib/tasks/.gitkeep create lib/assets create lib/assets/.gitkeep create log create log/.gitkeep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/index.html create public/robots.txt create script create script/rails create test/fixtures create test/fixtures/.gitkeep create test/functional create test/functional/.gitkeep create test/integration create test/integration/.gitkeep create test/unit create test/unit/.gitkeep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/index.html create public/robots.txt create script create script/rails create test/fixtures create test/fixtures/.gitkeep create test/functional create test/functional/.gitkeep create test/integration create test/integration/.gitkeep create test/unit create test/unit/.gitkeep create test/performance/browsing_test.rb create test/test_helper.rb create tmp/cache create tmp/cache/assets create vendor/assets/javascripts create vendor/assets/javascripts/.gitkeep create vendor/assets/stylesheets create vendor/assets/stylesheets/.gitkeep create vendor/plugins create vendor/plugins/.gitkeep
できたー!!
んでGemfile関連を削除(あくまでRailsを入れるためだけで、あとはRailsの中でgemファイルを管理するから洋梨)
この例だとRailsAppsディレクトリにはdemoディレクトリだけ残せばオーケーですね。
##### 追記
この後、demoディレクトリに移動して、bundle installを再び実行する事で、
bundle exec rails serverなど raisコマンドなどが実行出来るようになります。
$ cd demo $ bundle install --path vendor/bundle Fetching gem metadata from https://rubygems.org/........... Fetching gem metadata from https://rubygems.org/.. Resolving dependencies... Installing rake (10.0.4) Installing i18n (0.6.1) << 省略 >> $ bundle exec rails server => Booting WEBrick => Rails 3.2.13 application starting in development on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2013-04-23 01:02:23] INFO WEBrick 1.3.1 [2013-04-23 01:02:23] INFO ruby 2.0.0 (2013-02-24) [x86_64-darwin10.8.0] [2013-04-23 01:02:23] INFO WEBrick::HTTPServer#start: pid=18508 port=3000
rbenvを使ってみたよ
Perlのplenvを導入してみて大変便利だったので、
Rubyのrbenvを使ってRubyのバージョン切り替えとか簡単にやりたい!っと思い使ってみました。
※元々plenvはrbenvを参考に作られたそうです。
まずはgithubから持ってきます。
$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv Cloning into '/Users/sasakure/.rbenv'... remote: Counting objects: 1618, done. remote: Compressing objects: 100% (643/643), done. remote: Total 1618 (delta 1044), reused 1459 (delta 943) Receiving objects: 100% (1618/1618), 232.38 KiB | 171 KiB/s, done. Resolving deltas: 100% (1044/1044), done.
そしたらPATHを通します。
僕はzshを使っているので.zshrcに2行加えます。
export PATH="$HOME/.rbenv/bin:$PATH" PATH=~/.rbenv/shims:$PATH
zshの設定を反映して、ちゃんとrbenvコマンドが叩けるか確認します。
$ source ~/.zshrc $ which rbenv /Users/sasakure/.rbenv/bin/rbenv
次にRubyをビルドするためのruby-buildってプラグインを入れる必要があるそうです。
配置先はrbenvのpluginsディレクトリです。
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build Cloning into '/Users/sasakure/.rbenv/plugins/ruby-build'... remote: Counting objects: 1848, done. remote: Compressing objects: 100% (1124/1124), done. remote: Total 1848 (delta 761), reused 1610 (delta 548) Receiving objects: 100% (1848/1848), 250.77 KiB | 104 KiB/s, done. Resolving deltas: 100% (761/761), done.
さぁではRubyをインストールしてみますか。
とりあえず、インストール可能なバージョンを調べます。
$ rbenv install -l Available versions: 1.8.6-p383 1.8.6-p420 1.8.7-p249 1.8.7-p302 1.8.7-p334 1.8.7-p352 1.8.7-p357 1.8.7-p358 1.8.7-p370 1.8.7-p371 1.9.1-p378 1.9.2-p180 1.9.2-p290 1.9.2-p318 1.9.2-p320 1.9.3-dev << 長いので省略 >> jruby-1.7.3 jruby-1.7.4-dev maglev-1.0.0 maglev-1.1.0-dev mruby-dev rbx-1.2.4 rbx-2.0.0-dev rbx-2.0.0-rc1 ree-1.8.6-2009.06 ree-1.8.7-2009.09 ree-1.8.7-2009.10 ree-1.8.7-2010.01 ree-1.8.7-2010.02 ree-1.8.7-2011.03 ree-1.8.7-2011.12 ree-1.8.7-2012.01 ree-1.8.7-2012.02 topaz-dev
いっぱいありますな〜
最新の2.0.0にしようかな
$ rbenv install 2.0.0-p0 Downloading ruby-2.0.0-p0.tar.gz... -> http://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p0.tar.gz Installing ruby-2.0.0-p0... Installed ruby-2.0.0-p0 to /Users/sasakure/.rbenv/versions/2.0.0-p0 $ rbenv rehash
さすがにRubyのインストールは結構時間かかりました。
インストール終わったら rbenv rehashコマンドしておきます。
どれどれ
$ rbenv versions * system (set by /Users/sasakure/.rbenv/version) 2.0.0-p0
このsystemというのは元々入ってるバージョンを指します。
これを2.0.0-p0にするにはrbenv globalコマンドを使用します。
$ rbenv global 2.0.0-p0 $ rbenv versions system * 2.0.0-p0 (set by /Users/sasakure/.rbenv/version) $ ruby -v ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin10.8.0]
ちゃんと切り替わりました。
rbenv globalコマンドではマシン全体のバージョンを切り替えますが、
ディレクトリ単位に指定したり出来るみたいです。
そこまで使う予定が無いので、それはまたそのうち!
Perl入学式in東京 #1 へ遅刻しました
以前から気になっていた「Perl入学式」というperl未経験/初心者向けのイベントが
ついに東京でも行われるという事で早速参加してみました。
[Zussar] http://www.zusaar.com/event/583008
[Perl入学式 公式ページ] http://www.perl-entrance.org/
仮にもPerlを2〜3年使っている僕が参加していいもんか迷ったけど、plenvやAMON2を使ったこと無いし、既に補欠だったしまぁいいかという事でエントリー!
そしたら繰り上がって参加する事ができました。
それなのに!! 昨晩に飲み過ぎて寝坊して遅刻しました orz
多くの技術者の方々が時間を割いて、しかも無料で開いてくれる勉強会で
遅刻とかホッント申し訳ありません。クズです僕は
第一回目の本日は「Perlを書くための環境構築」のような感じで、
私が到着した頃にはplenvによるPerlのインストールが行われておりました。
とりあえず、出遅れたので皆さんの進行を横目に
主催者papixさんのブログを参考にしてplenvのインストール!
手順はこんな感じ
まずはtokuhiromさんのgithubより持ってきます。
$ git clone git://github.com/tokuhirom/plenv.git ~/.plenv
僕はzshを使っているので.zshrcへ下記の2行を追記して反映
export PATH="$HOME/.plenv/bin:$PATH" PATH=~/.plenv/shims:$PATH
$ source ~/.zshrc
するとplenvコマンドが使えるようになるので、
「plenv available」でインストール可能なPerlを一覧表示できます。
$ plenv available perl-5.17.10 perl-5.16.3 perl-5.14.4 perl-5.12.5 perl-5.10.1 perl-5.8.9 perl-5.6.2 perl5.005_04 perl5.004_05 perl5.003_07
Perl入学式では5.16.3を使うという事で下記のようにインストール。
$ plenv install 5.16.3
Perlのインストールには結構時間が必要です。
んでもって終わったら確認してみましょう。ということで
「plenv list」コマンドを叩くと、インストールされているPerlのバージョンが確認出来ます。
$ plenv list 5.16.3 * system
アスタリスクが付いてるほうが現在有効になっているバージョンで、
元々入ってるPerlは「system」と表示されるようです。
ということで5.16.3に切り替えます。
$ plenv global 5.16.3 $ plenv list * 5.16.3 system
「perl -v」で5.16.3になっていればOK。
僕の場合どっちに切り替えても元々インストールされていた5.12.3から変わらなくて
「source ~/.zshrc」したらちゃんと切り替わるようになりました。
お次はcpanmのインストール
$ plenv install-cpanm
簡単!
僕は慌ててこれらのインストールと動作確認して、やっと追いついたー
ってとこでPerl入学式第一回目は終わってしまったけど、
実際は超ゆっくり細かく説明していて
Hello world表示したり、Acmeモジュールで易しくCPANモジュールの使い方を教えてくれたり、エディタとかも一人一人面倒見てくれる
そらもう大変素晴らしい勉強会でした。[http://perl-entrance-org.github.io/presentation/2013/perlentrance01-2/index.html#/title:title=
このスライドをベースに進めていました。]
はじめてplenvを使ってみたけど、これ超便利!
自分の作業PCやテストサーバーなんかには必ず入れたいですね。
バージョン毎の動作テストとか捗りますな。
参加者25人くらいに対して
サポートメンバーが10人くらい? とても手厚い!!
なんか補講(同じ内容で別の日にやる)があるらしいので、これからPerl始めてみたい人は是非参加すると良いと思いますよ!
主催のpapixさん。サポートメンバーの皆さん。会場を提供して頂いたSeesaa株式会社様
ありがとうございましたー!
宇宙ステーション演算子について解説してみた
Perlの食えない事情-演算子編を読んで、とても面白く演算子を学ぶ事が出来ました。
なかでも「宇宙ステーション演算子:-+-」はなかなか理解出来なかったので、僕なりに解説したいと思います。
その前に「ビーナス演算子:0+,+0」について触れておきます。
print '100MB' +0; # 100 print 0+ '5GB'; # 5 print 0+ 'TB'; # 0 print 'route3390' +0; # 0
上記ブログでも簡単な説明がありますが、Perlは文字列と数値などの型を区別して持つ事は出来ません。
StringとかIntとかがないんです。
計算しようとすれば数値として扱うし、文字列操作しようとすれば文字列として扱います。
そのため、'100MB'というような値は
数値として扱えば、「100」として、
文字列として扱えば「100MB」として評価されます。
ビーナス演算子という大した名前がありますが、ただ 0を足しているだけですね。
0を足すのは先でも後でも構いません。
♀という記号を横にしたように見えることから名付けられたのでしょうw
文字列の先頭が「数値」または「-」「+」の符号でない場合は0として評価されます。
さて、宇宙ステーション演算子の解説に入ります。
上記ブログでは優先順位の高いビーナス演算子という説明がありますが、
それは使い方についての話で、演算子は別の動作をしています。
print 0+ '100MB' x 3; # 100 print -+- '100MB' x 3; # 100100100
※「x」はカケルではなく繰り返し演算子です。
まず、ビーナス演算子のほうは優先順位が+より、xのほうが高いので下記のような評価になっています。
print 0+ '100MB' x 3; print 0 + '100MB' x 3; print 0 + '100MB100MB100MB'; print 100;
次に宇宙ステーション演算子です。
ビーナス演算子は二項演算子の「+」が使われているのに対し、
こちらは単項演算子の「+」と「-」が使われています。
perldocに説明があります。
print -+- '100MB' x 3; print -+ '-100' x 3; print - '-100' x 3; print '100' x 3; print '100100100';
単項演算子の「-」は文字列を数値として評価した後、+/-の符号を反転します。
単項演算子の「+」は何もしません。
これ例えば下記のようにするとエラーになります。
print -- '100MB';
「--」とするとデクリメント演算子になってしまうため、引数に直接値を渡すんじゃねーってエラーになってしまうんです。
それを防ぐために「-+-」としてるんですね。
いまさら素数戦争のdankogai.plを読んでみた
「10000番目までの素数の和を求める」
というお題をいかに早く算出するか!というものでした。
私も参加ダメダメながら参加して楽しんでいました。私の記録はこちら
そこで気になっていたのが「殿堂」となっていたdankogai.pl
length q cmp lc and print chr oct oct ord qw q do q and print chr oct oct ord q mkdir m and print chr oct oct ord qw q for q and print chr oct oct oct ord q eq le and print chr oct ord uc qw q bind q and print chr oct ord uc q each ne and print chr oct oct ord qw q dump q and print chr oct oct oct ord q eq ne and print chr oct oct oct ord q eq ne
なんじゃこりゃ?本当にPerl? って感じですよね。
でも実行すると確かに10000番目までの素数の和である496165411が表示されます!!
当時は感心だけして、どうなっているのかまで関心は沸いていませんでした。
(漠然とすごいなー danさんってすごいんだなーって)
あれから半年、、
いまさらちゃんと読んでみたいと思います。
一番左からじっくり見ていってもいいですが、パッと目につくのはprintでしょうか。
そして、printに注目すると、必ずその前にandがあることが分かります。
length q cmp lc and print chr oct oct ord qw q do q and print chr oct oct ord q mkdir m and print chr oct oct ord qw q for q and print chr oct oct oct ord q eq le and print chr oct ord uc qw q bind q and print chr oct ord uc q each ne and print chr oct oct ord qw q dump q and print chr oct oct oct ord q eq ne and print chr oct oct oct ord q eq ne
andというのは&&と同じです。
&&は下記のようにifとかで使うやつです。
my $sasa = 1; my $kure = 1; if ($sasa && $kure ) { print 'sasaとkureがどちらもtrueと評価されるから表示される'; } #こんな使い方も出来る $kure && print '&&の左辺がtrueならこのprint文も評価される'; $kure || print '&&の左辺がtrueならこのprint文は評価されない';
dankogai.plではandを使う事で、本来なら;(セミコロン)で区切るような
処理を1行でやってしまっているんですね。
ちょっと読み易いようにandを削除して、分けてみましょ
length q cmp lc; print chr oct oct ord qw q do q; # 4 print chr oct oct ord q mkdir m; # 9 print chr oct oct ord qw q for q; # 6 print chr oct oct oct ord q eq le; # 1 print chr oct ord uc qw q bind q; # 6 print chr oct ord uc q each ne; # 5 print chr oct oct ord qw q dump q; # 4 print chr oct oct oct ord q eq ne; # 1 print chr oct oct oct ord q eq ne; # 1
こうしてみると、驚愕の事実が分かります。
「これ、、計算してない、、」
この時点ではどうして数字が表示されるのか、分かりませんが
素数戦争の答えである496165411をそのまま表示している事実が分かりました。
すげーマジカルな事やって計算してるのかなー って思ってたのに悔しい、、笑
ま、気を取り直して理解を進めます。
次に注目すべきはordという演算子と、その後ろの固まりです。
length q cmp lc; print chr oct oct ord qw q do q; # 4 print chr oct oct ord q mkdir m; # 9 print chr oct oct ord qw q for q; # 6 print chr oct oct oct ord q eq le; # 1 print chr oct ord uc qw q bind q; # 6 print chr oct ord uc q each ne; # 5 print chr oct oct ord qw q dump q; # 4 print chr oct oct oct ord q eq ne; # 1 print chr oct oct oct ord q eq ne; # 1
その部分だけ実行してみましょう。
print ord qw q do q; # 100 print ord q mkdir m; # 107
これは下記のように評価されています。
print ord 'do'; #100 print ord 'kdir'; #107
これは私もよく分かっていないのですが、
qw q 文字列 q で '文字列' と評価されるようです。
または、
qwを書かない場合は q の次に来る文字から、またその文字までをシングルクォートで囲っていると評価するようです。
(perldocとかに書いてあるんでしょうか。探せなかったので誰かおしえてー(>_<) )
追記:
perldocに書いてありました。
「クォートとクォート風の演算子」のところですね。
Perlではqw{}の括弧は別に何でも代用が出来て、よく使うのだとqw//というのがありますね。
区切り文字が括弧ではない場合は前後で同じ文字があれば、それを区切り文字と評価するようです。
@tsucchiさんありがとうございます!
ordという演算子は引数の「一番先頭の文字」のASCIIコードを返します。
print ord 'A'; # 65 print ord 'Aiueo'; # 65 <-先頭のAしか評価されていない
なのでさっきのも
print ord 'd'; #100 print ord 'k'; #107
こうやってるのと一緒。
わざとPerlの予約語のようにみせてただけなんですねー。
それらを踏まえると下記のようになります。
length q cmp lc; print chr oct oct ord 'do'; # 4 print chr oct oct ord 'kdir'; # 9 print chr oct oct ord 'for'; # 6 print chr oct oct oct ord 'q l'; # 1 print chr oct ord uc 'bind'; # 6 print chr oct ord uc 'ach n'; # 5 print chr oct oct ord 'dump'; # 4 print chr oct oct oct ord 'q n'; # 1 print chr oct oct oct ord 'q n'; # 1
length q cmp lc; print chr oct oct 100; # 4 print chr oct oct 107; # 9 print chr oct oct 102; # 6 print chr oct oct oct 113; # 1 print chr oct 66; # 6 print chr oct 65; # 5 print chr oct oct 100; # 4 print chr oct oct oct 81; # 1 print chr oct oct oct 81; # 1
oct演算子についてはこちらで詳しく説明されていました。
今回のケースでいえば引数を8進数とみなして、10進数への変換を行います。
chr演算子についてもこちら
ord演算子の反対ですね。ASCIIコードから文字に変換します。
oct演算子を2回、3回と使う事で、
目当ての数字にするためのASCIIコードにしているんですね。
最後に先頭にあった行について
length q cmp lc;
こちらは下記のように評価されます。
length 'mp l';
そして、lengthですから4という数値が返ります。
しかしprintしているわけではないので、そのまま何も表示されません。
dankogai.plはこの部分が無くても同じ結果になります。
きっと最初にprintが来てしまうと不思議さが半減してしまうからではないでしょうかw
今回ブログにまとめるにあたり、詳しく調べていたら
こういったコードがppencodeといわれる物だという事が分かりました。
とても参考になったページ
■TAKESAKOさんの ppencode が何で動くのか分かった。
2006年にTAKESAKOさんという方がYAPCで発表していたそうで、当時はだいぶ話題になっていたんですねー!
私はこのコードを会社の同僚と楽しみながら読む事が出来ましたし、
Perlへの理解が進んだように思います。
たくさんの人に感謝☆
AcmeモジュールをCPANにあげてみた
先日Perl Beginnersに参加したときにLTで話した
Acme::ReplicaというモジュールをCPANにアップしました。
Acme::Replicaについて
精巧に作られた食品サンプルのように、見た目は本物そっくりですが 実際には食べれない値を返すモジュールです。
暇なときにでも使ってみてください。
use 5.010; use Acme::Replica; my $rep = replica_of( 'sasakure' ); if ( $rep eq 'sasakure' ) { say 'ここは表示されない'; } else { say 'ここは表示される'; say $rep; # sasakure }
ifの評価ではfalseになるのに、sasakureってちゃんと表示される。
どういう事かというと
表示しても字としては出てこないけど、実際はバイト単位では余計なデータが付けているから。
ハッシュを渡すとキーに余計なゴミバイトが付くようになってます。
use 5.010; use Acme::Replica; use Data::Dumper; my %rep = replica_of( { japanese => 'sushi', amelican => 'hotdog', } ); say Dumper ¥%rep; # $var1 = { # japanese => 'sushi', # american => 'hotdog', # }; say $replica{japanese}; # エラーになる $replica{japanese} = 'sukiyaki'; say Dumper ¥%rep; # $var1 = { # japanese => 'sushi', # japanese => 'sukiyaki', # american => 'hotdog', # }; say $replica{japanese}; # sukiyaki
あくまでReplica(模造品)なので同じようで、違うハッシュが返ってきています。
食品サンプルが並んだハッシュに自分でスキヤキを入れたら、
スキヤキだけはちゃんと(食べれ|取れ)ます。
記念すべき僕の初Acmeモジュール :-P
Ver0.02ではMakefile.pmに初めてinc::Module::Installを使ってみました。
配列やハッシュを引数で渡すとき、使い易さでいったら、そのままブッコむ!
って思ったんですが、
後で引数を増やしたい時とか困るな〜って思ってリファレンス渡しにしました。
こういうAcmeモジュールほど、気軽にアドバイスいただけちゃったり
Pull Reqもらえるんじゃないかとwktkしてます。