Rubyの最近のブログ記事
よくわからずに思ったこと、感じていたことを連ねました。
勘違いも甚だしいーな記述があるかもしれませんが。ご一笑ください。
なお引用部に関しては、レイアウトの都合上、文脈を変えない程度で改行等をほどこしてありますことをご了承ください。
文体や語感、リズムを重んじる方はぜひ引用元へどうぞ。
私は、言語に二つの相反するものを期待している。一つは、「たいていのことがサクっと当たり前に出来る」こと。
Larry Wall が言うところの「殺速性」(whipuptitude)だ。これがないと書いてて疲れてしまう。大リーグ養成ギプスを常に着たまま生活したい人などいるのだろうか。星飛雄馬本人だっていやがってたのに。しかし、それだけじゃ私には物足りない。「言われなきゃ思いもつかなかった言い回しをその言語の範囲内で言う」、複殺性(manuplexity)も必要なのだ。皮肉ではあるが、これがないと複殺なものは複殺なままなのだ。
Perlの偉い人のブログを読んで「あー、だから自分は Ruby を選んだのか」と思った。
プログラミング言語にはそれぞれ個性があって、その個性は入門書にまで "(同一言語なのに)記述の統一性のなさ" という形で表れる。そしてそれは僕の中で、プログラミング学習のハードルになっていたのだ。Ruby に会うまでは。
Rubyのよさ。
それは Ruby はなんていったて入門書が たのしいRuby 第2版 Rubyではじめる気軽なプログラミングしかないでしょう。
この選択肢のなさはある意味魅力だったわけ。他の人が書いたソースもこの本の流儀に則ってる可能性が高いだろうから理解しやすいんじゃないかって。
実際に Ruby をやってみると、each の気持ちよさが何とも言えなかった。
流れ作業丸出しな感じ。これが気持ちよかった。
想像するならばめんどくさがりの上司が、たまりにたまった書類に承認印をめくらめっぽう押す感じ。ティッシュ配りのアルバイトが、誰彼かまわず「お願いしゃーす」と配っている感じ。脊髄反射なのに惰性でダルダル、素早さなんて微塵もない感じ。まじでさいこー。
この感じを得られたのは幸運だった。プログラミングって流れ作業を微分することだったんだ、と気付いた。
この気付きを Perl でも得られたのか、Python でも得られたのかは謎である(そう、C では得るところまで理解できなかった)。
まだ、Ruby で満足に機能するものを作り上げたわけではない。
でも、とにかく気付きを得られたこの一点だけで Ruby が存在し Ruby と出会えたことに感謝している。
追記:2008/06/25 Ruby に関して、入門書が~しかないでしょう、って書いてしまいましたが、単純にそれしか知らなかったってことなんですよね。これは誤解を招くなあ。
アスキー (2000/10)
売り上げランキング: 59751

2000年出版の本ですが、今でもとっても参考になります
邪道上等!
プログラマが楽しくよめる一冊それにしてもHack系の本の言葉使いってなんだろうね。
その昔、ハッピー・ハッカー (ハッカージャパンBOOKS (5))って分厚い本があって、
そこには"ダータ"とか"ピーコ"だとかいう言葉が並んでいた。
これってハッカー・ジャパン語なのかしら?
"割れず"とかと同じ種類のものなんだろうけど、発生過程が気になるところ。
先日の携帯/SO702i-故障事件。
ソニー製品は概して接触部が弱い。
Mova携帯のジョグダイヤルも、メモリースティックウォークマンの早送りのツマミも、
VAIOの液晶ヒンジ部、ノートのメモリ固定部も。ぜんぶそこだけ駄目になった。
よく考えてみると、ウォークマンの故障以外は全部致命的な故障なんだよ。
雑なのか、精密に弱くしてるのかわからんところがSONYだよな。
でも携帯に関してはインターフェースがSONYのそれしかわからんからまた使ってしまうのかな。
で当の携帯は結局修理に出した。
いまのところ連絡待ち。
→無償修理、もしくは
→最悪有償(5万くらいらしい)→修理依頼せず機種変
という二択で考えている。
それにしてもDoCoMoショップの店員は態度がおかしい。
他を知らないからそんなこと言ってはいけないのだろうけど、
単純におかしく感じたことを書いてみる。
連絡先を記入する際に、「ご都合のいい時間帯もお書きください」と言われた。
そこで9時か20時と記入。
すると「その時間は営業時間外ですので他の時間をお書きください」と言われる。
先に言えよ。何、一手間惜しんで客にその手間押しつけてんだよ。
他にもある。
SO702iはメモリースティックDuoを外部メモリとして使用することが出来る。
ってことはそれでバックアップをとるわけじゃないか、普通。
で修理時には代替機借りるよね。
けど、メモリースティックDuoに対応した機種は無い、と言う。
まあ、実際古いタイプだし、今はMiniSDだかMicroSDだかが主流なんだからしょうがないのはわかる。
でもさ、「(メモリースティックDuoを)使える機種は代替機に無いの?」って聞いた僕に、
「ないですねー。通常はMiniSDですから」って返しはねーだろーよ。
こっちは思わず「通常?通常ってなんだよ!」って言ってしまったよ。
そしたらはっとして、preminiのシリーズものだと思うけど古い機種持ってきた。
最初からやれ、と思うんだ。
故障することはあるし、旧機種をいつまでもサポートしてらんないっていうのはわかる。
でも、使っている人はいるわけだし、使ってくれって言ったのはお前等だろうが。
バックアップはとりましょうね、とか広報活動しておきながら、故障時の対応ができないってどういうこと?
それはあなた、身勝手にもほどがあるよ。企業としておかしいですよ。
家族割りとかでついでに親の名義に入ってるとする。
で、大学生になったとかで親元を離れ上京したとする。
で、携帯壊れましたってことになる。僕と同じ状況になったとする。
もちろん修理か機種変したいよ。お金もあったとするよ。
でも親に確認とらなきゃいけない。それは親が名義人だから。
そのとき携帯からデータ抜け出せなきゃ手も足もでないよ。
実家に親がいればいいさ。実家の電話でつながるもんな。
でも一家離散してて携帯でしか連絡できない家族だったらどうするのさ。
現に僕がそうなんだよ。
修理も頼めない、機種変もできない。新規で契約しろってこと?
でもデータが無ければ携帯あっても意味ないし、こちとらバックアップは異端のメモステDuoだよ。
からっぽの最新携帯があっても結局何もできやしないよ。
DoCoMoショップすべてがそうだとは思わないし、僕の行ったところがたまたま悪かったんだろう。
でも、そんな人間許すなよ。
自社の製品を誇りに思っていたらそんないい加減な対応、環境をそのままにしておくな。
たのしいRuby 第2版 Rubyではじめる気軽なプログラミング
p322 『第16章 FileクラスとDirクラス』においてまたも誤植が。
FileUtils.compare(from,to)
とあるが、これでは動作しない。
fileutils - Rubyリファレンスマニュアルにあるように
FileUtils.compare_file(from,to)
でやっとこ動作することを確認。
これはまだ
『たのしいRuby 第2版』正誤表にも出ていない模様。
現在何版何刷まで出版されているのかわからないけど、これってもしかして、
著作権保護のトラップってやつかしら、と思った。
ウミガメのスープにも問題としてあった。
地図でいうと-存在しないはずの島をわざと記入する。
辞書でいうと-でたらめな言葉と用例を載せる。
そんな都市伝説みたいなこと実際にやるのかしらね?
けれどよくよくたのしいRubyを見直してみると、
どうやらそんな感じじゃないなー。
p321の最下段
FileUtils.rm_r(path)
FileUtils.rm_f(path)
も実は誤植で
FileUtils.rm_r(path)
FileUtils.rm_rf(path)
なのである(これは正誤表にも出てる)。
ってことは罠っていうより、ここの校正担当したやつがだめなんじゃねーか、と思えてきた。
いや、しかししかし複数ページにわたってあえて間違えることによって、より効果的に著作権侵害から身を守っているのか?
うーむ。
知らん!
本日休みだったということで軽い読書。
以前から気になっていた、ポール・スローンのウミガメのスープ―水平思考推理ゲームをBOOK OFFで購入する。300円。
表題作である『ウミガメのスープ』以上のインパクトある問題が少なくて、正直がっかし。
訳も中途半端だからアンフェアな叙述トリックが多いし。
水平思考というのが、この本書を則る思考法です。
いろいろな側面から仮説をぶち当て、複数の問題を全て解決する説を見つけるのです。
宮本茂のいうところの<<アイディア>>がまさにそれでしょう。
糸井 まえに岩田さんと話したときに、
「アイデアというのはなにか?」
という話をしたじゃないですか。
岩田 宮本(茂)さんのことばですね。
糸井 そうです。つまり、宮本さんによれば、
「アイデアというのは
複数の問題を一気に解決するものである」
ということなんですが、
この話を事務所のみんなにしたところ、
ものすごく感心されまして。
せっかく岩田さんがいらっしゃってることだし、
あの宮本さんの発言の意図と、岩田さんの分析を
くわしく聞かせてもらえたらなと思うんですが。岩田 あれは、ゲームをつくってるときに、
宮本さんが言ったんですよ。
ですから、宮本さんは
ゲームをつくるときのひとつの方法論として、
おっしゃってたんですけど、
わたしは、ゲームづくりに限らず
万能な考え方だと思うんですよね。
HOBO NIKKAN ITOI SHINBUN - 1101.comより
さすがちゃぶ台返しerです。いうことが違います。
また、こちらでは<<水平思考>>と直接使われております。
- 横井の哲学に、「枯れた技術の水平思考」という言葉がある。
横井軍平 - Wikipediaより
どちらも奇しくも任天堂を代表したエンジニア。そりゃあ新しいものを作るわけだわ。
Rubyはやっとこさ 第16章-FileクラスとDirクラス- に突入。まあまあゆっくりやりましょう。
6月くらいまでにはRuby技術者認定試験(Ruby Association Certified Ruby Programmer)を受けて合格したいものです。
昨日の夜勤から、今の今までずっと悩んでいた。
以下はたのしいRuby 第2版 Rubyではじめる気軽なプログラミングのp154にあるwc.rbであるのだが、
#### wc.rb #####ltotal=0
wtotal=0
ctotal=0ARGV.each{|file|
begin
input = open(file)
l=0
w=0
c=0while line = input.gets
l += 1
c += line.size
line.sub!(/^\s+/,"")
ary = line.split(/\s+/).size #*1.原文ママ
w += ary.size #*2.だからここで悩んだ
endinput.close
printf("%8d %8d %8d %s\n",l,w,c,file)
ltotal += l
wtotal += w
ctotal += c
rescue => ex
print ex.message, "\n"
end
}printf("%8d %8d %8d %s\n",ltotal,wtotal,ctotal,"total")
##[EOF]
例外処理云々じゃなくて、*印のところで頭を抱えた。
ary = line.split(/\s/).size ##*1ってのは文字列 line を split メソッドにより空白で分割する。そして line は文字列オブジェクトを格納する配列となる。
んで、 size がインデックス数を返し、変数 ary に代入されるわけだしょ。うんそれはわかる。でもね、
w += ary.size ##*2
そうすっとこりゃなんじゃ?line.split(/\s/).size.sizeってこと?んー意味不明。
ここで得たいのは単語数なのであるから、文字列を、空白文字区切りにすると(配列の)要素がいくつできるかってことだよね。
line.split(/\s/).size
で既に欲しい数値はでてるわけだから直接、
w += line.split(/\s/).size
しちゃえばいいのに。 ary がなんのためにいるの?
すっげえ気になるからこんなの書いてみた。
#### test.rb ####file=ARGV[0]
input=open(file)while line = input.gets
line.sub!(/^\s+/,"")
ary = line.split(/\s+/).size
ary2 = ary.size
print "line.sub!#=>",line,"\n"
print "line.split.size#=>",line.split(/\s+/).size,"\n"
print "ary.size#=>",ary.size,"\n"
print "ary2#=>",ary2,"\n"
print "ary2.size#=>",ary2.size,"\n"
print "=========================\n"
end
input.close##[EOF]
これ引数をファイル名にして実行してみるとわかると思うんですが、
- ary.size
- ary2
- ary2.size
全部返す値が一緒になります。ずっと。
ary2 = ary.size
してるから一緒なのはわかるけどずっと同じ値を返すのはちょっとなんでかなって思う。
で調査したところ、
Array#size の size ってことは 整数n.size てことですわな。
でこれまた irb かなんかでやってみてもらえればわかると思うんですが、
4.size も 100.size も 100000.size も全部 4 を返します。
じゃあ 1000000000000000000.size も 4 かっていうとそれは違って 8 になります。
irb(main):070:0> 4294967295.size
=> 4
irb(main):071:0> 4294967296.size
=> 8
が分かれ目みたいですよ。
でやっとこさRubyリファレンスマニュアル - Rubyリファレンスマニュアルを調べる。
Integer - Rubyリファレンスマニュアルによると、
- size
整数の実装上のサイズをバイト数で返します。
現在の実装では Fixnum は、sizeof(long) 固定(多くの 32 bit マシンで 4 バイト)、Bignumは、システム依存です。
だそうな。実装上のサイズっていうのが雰囲気でしかわからんのだけど、
「まあ 4 は 100 より少ないけど、だからって紙に書くときインクの量が 1/25 ですむってわけでもないよね」って感じかな。
ふーん。これはこれで勉強になった。いやしかし、じゃあ wc.rb のあれはいったい。
てなとこで見つけましたよ。
サンプルのバグ発見してしまった・・・サイズの処理が間違ってる。『たのしいRuby 第2版』正誤表 次の版では直っているそうです。サポートページをブクマしとこう。
正誤表ブックマークさせていただきましたともさ。
LPIC-1 といい Ruby といい wc は鬼門だ。
(Linux 教科書 LPICレベル1 第3版(CD-ROM付) (Linux教科書)
では修正されているが、第2版では テキスト処理フィルタの項で、 wc の説明が、表示結果とそぐわない部分があった。)
案外早くプロメトリックが動いたんですね。もっと先のことになるかと思っていたのに。
机上の筆記試験で3回行われていたそうなんですが、なにか目処がたったんでしょうか。
こんなに早く実施されるなら最初からプロメトリックでやればいいのに、と思わないでもないです。
さて、前回のエントリであげたRuby / filename、file、txt なんて変数三つも使う理由 / bashの続き。
2. [ もっと人間的な動作で例えられないのかな ]
こんな感じでどうでしょうか。
#otetsudai.rb
reizouko_name = (ARGV[0])
akeppa = open(reizouko_name)def houkoku(guzai)
print guzai
endwhile nakawomiru = akeppa.gets do
houkoku(nakawomiru)
end
akeppa.close
#[EOF]
では説明を。
まず、思い浮かべて頂きたいのはよくある核家族の風景です。時は日曜のお昼です。
小学生の太郎くんは目を覚まします。ちょっとお腹がすいています。
そこで母親に何か作ってとせがみます。日曜日のブランチです。
居間でテレビを視ている母親は「じゃあ冷蔵庫の中身を全部教えて」と言いました。
どうやらいつものように中の具材を聞いてから、何を作るか決めるようです。
太郎くんの家には冷蔵庫が2つあります。
どっちの冷蔵庫か尋ねると母親は「奥の方」とテレビを視ながら答えました。
太郎くんは件の冷蔵庫を開け、全ての具材を覚え(冷蔵庫は閑散としていたので)、いっぺんに母親に言おうとしましたが、
母親が物覚えも悪く、人の話もろくに聞かない人だと言うことを知っていたので、一つずついうことにしました。
具材を全て言い終えると、太郎くんは昼ご飯を作る母親に代わってテレビを視ようとしましたが、
以前、冷蔵庫を開けっ放しにして怒られたことを思い出しキッチンに戻って冷蔵庫を閉めました。
ポイントは
1."「じゃあ冷蔵庫の中身を教えて」"-という母親の台詞
2."どうやらいつものように中の具材を聞いてから"-というこの家庭の習慣
3."どっちの冷蔵庫か尋ねると母親は「奥の方」とテレビを視ながら答えました"-という指定
4."一つずついうことにしました"-という伝達法の選択
5."キッチンに戻って冷蔵庫を閉めました"-という資源の適切な利用
1."「じゃあ冷蔵庫の中身を全部教えて」"-という母親の台詞
これが
ruby otetsudai.rb
という実行にあたります。
2."どうやらいつものように中の具材を聞いてから"-というこの家庭の習慣
習慣化しているので、
def houkoku(guzai)
print guzai
end
メソッドになっています(ここは僕自身ちょっと理解が足りません)
3."どっちの冷蔵庫か尋ねると母親は「奥の方」とテレビを視ながら答えました"-という指定
ここの指定が、
reizouko_name に代入される引数 ARGV[0] となり、
ruby otetsudai.rb reizouko_oku
と実行すればいい、ということになります。
4."一つずついうことにしました"-という伝達法の選択
ここは
while nakawomiru = akeppa.gets do
houkoku(nakawomiru)
end
ということになります。 akeppa.gets が具材を一つずつ伝えるという解釈です。
また、1."「じゃあ冷蔵庫の中身を全部教えて」"-という母親の台詞にある、
「全部教えて」という母親の指示に応えて、while を使用しています。
5."キッチンに戻って冷蔵庫を閉めました"-という資源の適切な利用
これは最後の行、
akeppa.close
にあたります。説明は不要ですね。
reizouko.rbと同一のディレクトリに
./ reizoukoA
./ reizoukoB
を適宜作成し試してみましょう。
$ ruby reizouko.rb reizoukoA
#=>
じゃがいも
にんじん
カレールー
にら
白菜
もやし
醤油
ワイン
コーラ
卵
となりました。これを受けて太郎くん母が何を作るか、というプログラムを組んでみるのも面白いかも。
僕はまだそこまでのレベルにはいけませんが。
それにしても抽象化→具象化は難しいな。逆は簡単なのに。
Sanmba の他にも Ruby を再学習しているところ。
たのしいRuby 第2版 Rubyではじめる気軽なプログラミング
の50ページにこんなソースが。
#read_txt.rb
filename = ARGV[0]
file = open(filename)
txt = file.read
print txt
file.close
これは read_txt.rb の引数(ファイル名)を
・開いて
・読み込んで
・出力して
・閉じる
っていう挙動をします。
read_txt.rbと同じ階層内に下記のようなファイルを置いて、
#abcd.txt
aaa
bbb
ccc
ddd
eee
で実行。
$ ruby read_txt.rb abcd.txt
#=>
aaa
bbb
ccc
ddd
eee
と出力されるわけなんですな。
でもなんかすっと落とし込めないんだよね。
実際に頭に入ってこない。
っていうのも
1. [ filename、file、txt なんて変数三つも使う理由 ]
2. [ もっと人間的な動作で例えられないのかな ]
という二点から。
実際に試してみる。
まずは1. filename、file、txt なんて変数三つも使う理由から。
先述したread_txt.rbでなるべく変数を使わないで書いてみる。
#kaitemita.rb
print open(ARGV[0]).read
open(ARGV[0]).close
で実行する。
$ ruby kaitemita.rb abcd.txt同じやーん。結局は見易さなの? いやいやそんなはずはない。変数使用の理由は絶対にあるはず。 そこで次の項で扱われている、getsメソッドを使用した gets_txt.rb と 変数を使わないバージョンを続けて書いて試してみる。
#=>
aaa
bbb
ccc
ddd
eee
#tsuduketekaita.rb###gets_txt.rb
filename = ARGV[0]
file = open(filename)
while txt = file.gets do
print txt
end
file.closeprint "\n===========","\n"#区切り
###変数なしで書く。
while open(ARGV[0]).gets do
print open(ARGV[0]).gets
end
open(ARGV[0]).close
実行
$ ruby tsuduketekaita.rb abcd.txt
#=>
aaa
bbb
ccc
ddd
eee
===========
aaa
aaa
aaa
aaa
aaa
(ループするのでCtr + Cで終了)
tsuduketekaita.rb:13: Interrupt
なんか挙動が違いますね。
終了時のメッセージを見ると13行目の処理を行っていたとこでしたとな。
これ何回か繰り返してメッセージをみてみるとわかると思いますけど、
とりあえず変数無しバージョンは while のところを延々と回ってるみたいですね。だからループするわけ。
そして "aaa" ばっかり出力されちゃうのは、毎回 open(ARGV[0]).gets しちゃうからなんですね。
つまり新しくファイルオブジェクトを open してから gets を繰り返すから最初の一行しか print されないんだわ。
で、ずっと一行目だから nil にならねーんでループってわけ。
んー納得、と思ったところでひらめき。もしやこういうこと?
#!/bin/bash
a=`date`
date
sleep 10
date
echo ${a}
なーるほどね。実行してみるべし。
おもったより長くなってしまったので
2. [ もっと人間的な動作で例えられないのかな ]
については次のエントリで。
ソフトバンククリエイティブ (2006/08/05)
売り上げランキング: 4000
i = 1 while i <= 100 if i % 3 ==0 && i % 5 == 0 puts "FizzBuzz" elsif i % 3 == 0 puts "Fizz" elsif i % 5 == 0 puts "Buzz" elsif puts i end i+=1 end
Rubyはじめたんですよね。
Cはどうしたの?ん?
つまづきました。
CCNAとってから暇があったからやるべきだったかもしれないんですが、
Ubuntuで遊んだり、LPIC-1勉強しようかと思ったりで、はあ。
CCNAが案外すんなりとれてしまったのと、
その勉強が資格を取るための勉強でしかなかったことに、
嫌気がさしてしまったのとで、はあ。
仕事に使えるわけでもないし、それならサーバ構築できたときに、
役に立つであろう、Rubyを学習しておくのもいいかなあなんて。
確かに簡単ではありますね。文法上の問題でしょうか。
ものすごい簡潔、という感じではあります。
オブジェクトとかクラスとかそこらへんがするっと飲み込めた感じ。
実はJAVAにも手を出したことがあるんですが、そのときは、
まったく理解できませんでした。オブジェクト指向ってなんだべさ?
そんな感じでした。
しかし、Rubyに関してはそんな感じではないんですよね。
やっぱり厨臭いものが好きなのかな僕は。



![冷蔵庫で食品を腐らす日本人 [朝日新書059] (朝日新書 59)](http://ecx.images-amazon.com/images/I/11gqCqfaUeL.jpg)


