Archive for December, 2009
* Ruby Facets(Core)でおしゃれRuby!
Posted on December 24th, 2009 by tomoya. Filed under 書いた.
(この記事はRuby Advent Calendar jp: 2009の24日目です. 前日はursmさん、明日はtechnohippyさんです。
普段、技術的なことはwww.nicecabbage.comで書いていますが、今回は企画ものなので日本語で書いてみます。)

メリークリスマスイブ!
こんな聖なる夜に、他人のブログを読んでいる人なんていないと知りながら、投稿します。
この記事では、「Ruby Facets」ライブラリを紹介したいと思います。
Rubyは簡単に基本クラスを拡張できることから、より便利に、あるいは暗黒的に使うためのライブラリがたくさんありますね。”2.days.ago”で一躍評判となったRailsのActiveSupportや、”require :merb / :core_ext / :lib”でおなじみのMerbのextlibが有名です。
Ruby Facetsも、そんなライブラリのひとつ。Rubyをほんのりおしゃれに、ちょっぴりスパイシーにしちゃいます。
どんなことができるのか、つまみ食い形式でご紹介しましょう。
Array
Arrayの積を求める(デカルト積というらしい)
%w(Chapman Cleese Gilliam) ** %w(ham egg spam) #=> [["Chapman", "ham"], ["Chapman", "egg"], ["Chapman", "spam"], ["Cleese", "ham"], ["Cleese", "egg"], ["Cleese", "spam"], ["Gilliam", "ham"], ["Gilliam", "egg"], ["Gilliam", "spam"]]
組み合わせを求める
%w(Chapman Cleese Gilliam).combination(2).to_a #=> [["Chapman", "Cleese"], ["Chapman", "Gilliam"], ["Cleese", "Gilliam"]]
Arrayのおしりに詰め物をする
%w(k t k r).pad(10, "!") #=> ["k", "t", "k", "r", "!", "!", "!", "!", "!", "!"]
セパレータを複数指定できるjoin
["Crosby", "Stils", "Nash", "Young"].conjoin(', ', ' & ') #=> "Crosby, Stils, Nash & Young"
Enumerable
EnumerableをごにょごにょするときのECOモード「Denumerable」
(select, mapなどはフィルタのように働き、中間のオブジェクトを生成しない)
arr = (1..100).to_a class << arr include Denumerable end puts arr.select{|n| n%10==0}.map{|n| n**2}.to_a
グループ化
(1970..1990).group_by{|y| y < 1989 ? 'showa' : 'heisei' } #=> {"heisei"=>[1989, 1990], "showa"=>[1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988]}
MapしてHashしたいから、Mash!
[:year, :month, :day].mash{|sym| [sym, Date.today.send(sym)]} #=> {:day=>24, :month=>12, :year=>2009}
最頻出要素(modeは統計用語だそうです)
%w(ham egg spam egg spam egg).mode #=> ["egg"]
出現する確率
%w(ham egg spam egg spam egg).probability #=> {"egg"=>0.5, "spam"=>0.333333333333333, "ham"=>0.166666666666667}
出現する個数
%w(ham egg spam egg spam egg).frequency #=> {"egg"=>3, "spam"=>2, "ham"=>1}
エントロピー増大の法則
%w(ham egg ham egg ham egg).entropy #=> 1.0 %w(ham egg ham egg ham spam).entropy #=> 1.45914791702724 %w(ham egg spam! egg ham spam).entropy #=> 1.91829583405449 %w(ham egg spam! spam!! ham spam).entropy #=> 2.25162916738782 %w(ham egg spam! spam!! spam!!! spam).entropy #=> 2.58496250072116 %w(spam!!!! egg spam! spam!! spam!!! spam).entropy #=> 2.58496250072116 %w(spam!!!! spam!!!!! spam! spam!! spam!!! spam).entropy #=> 2.58496250072116
Hash
Hashだって、時にはArrayのように振る舞わせたいものです。
{ :john=>'lennon'} + { :ono=>'yoko'} #=> {:john=>"lennon", :ono=>"yoko"} { :john=>'lennon', :ono=>'yoko'} - { :john=>'lennon'} #=> {:ono=>yoko} { :john=>'lennon', :ono=>'yoko'}.join(' ', ', ') #=> "john lennon, ono yoko"
Object
Object#newのProc化
class Monty def initialize(name); @name = name end end %w(Chapman Cleese Gilliam).map &Monty #=> [#<Monty:0x1254a6c @name="Chapman">, #<Monty:0x1254a30 @name="Cleese">, #<Monty:0x12549f4 @name="Gilliam">]
Kernel
ファイル名、行番号つきデバッグ ‘d’(’g'とか’n'とかありますが、’d'もありますよ、ということで)
d variable
#=> [["Chapman", "Cleese", "Gilliam", "Idle", "Jones", "Palin"]] d.rb:5仲間に入ってる?
me = "tomoya55" monties = ["Chapman", "Cleese", "Gilliam", "Idle", "Jones", "Palin"] me.in? monties #=> false
困ったらユーザに聞くといい
ask "Oops, I encoutered unexpected problems. Do you want to debug me?"とまらないかも。。しれない。
loop do break if maybe end
maybeはtrueになる確率を指定することができる。
# Christmas Eve by Tasturo Yamashita maybe(0.01) ? 'she will come' : 'she will not'
だまれ!
silently do warn "It is a Chiristmas, stupid!" puts "We wish a Merry Chiristmas, We wish a Merry Chiristmas" STDERR.puts "****, explode!" end
alias devnull silentlyなどしてみるのもいいかもしれません
Stackable
文字列をスタックのように扱う
str = "0123456" class << str include Stackable end str.pop #=> 6 str.push("9") #=> "0123459"
Time
時の経過をはかる
Time.elapse{require 'active_support'} #=> 0.695170879364014 Time.elapse{require 'extlib'} #=> 0.185311079025269
1年前
Time.now.ago(1, :years)
1年後(引数のパターンが違うのがいやですね。こちらのCREDITはActiveSupportチームらしいです)
Time.now.advance(:years=>1)
Module
ラッパー(いわゆるデコレーター)
class ChristmasObject wrap(:inspect) do |orig, *args| "<We Wish>" + orig.call + "< a Merry Christmas!!>" end end p ChristmasObject.new #=> <We Wish>#<ChristmasObject:0x12535cc>< a Merry Christmas!!>
Symbol
~ではじまるSymbolは否定語
:friend.not? #=> false :'~friend'.not? #=> true
String
Stringにはわさわさとメソッドが追加されています。使いやすそうなものだけ。
"ero".bracket('(') #=> "(ero)" "ero".bracket('x') #=> "xerox" "santa".chars #=> ["s", "a", "n", "t", "a"] "santa clause".cleave #=> ["santa", "clause"] cleaveは「割く」という意味ぽい %q(/usr/bin/ruby).quote(:b) #=> "`/usr/bin/ruby`" %q(/usr/bin/ruby).quote(:s) #=> "'/usr/bin/ruby'" %q(/usr/bin/ruby).quote(:d) #=> ""/usr/bin/ruby"" %q("/usr/bin/ruby").dequote #=> "/usr/bin/ruby" "ham spam".rewrite([[/am/, "i"],[/\s/,'-']]) #=> "hi-spi"
まだまだありますがこのへんで、ふう〜
あまりここでは紹介していないけれど、メタプログラミングのための拡張もずいぶんなされているので、Rubyで黒魔術やるのが好きな向きには一見の価値ありだと思います。
ところで、Facets(Core)自体は、目新しい機能は何も用意しません。当たり前に使いたいメソッドを簡潔に実装したものの集まりにすぎません。たいていのメソッドの実装は数行程度で、多くても20行程度。
おそらくRubyプログラマなら、似た振る舞いをするメソッドを実装した経験も数多くあるでしょう。
このライブラリを使用する目的は、
- 車輪の再発明なしに
- 簡潔に
- 正しいメソッド名で
書けることができることにつきます。つまり、コードが読みやすくなり、メンテナンスしやすくなるのですね。
正しいメソッド名とというのは、かなり重要です。
われわれ、へっぽこ日本語プログラマは、痛いクラス名、痛いメソッド名を量産してしまいがちなので、こういったライブラリから適切な英単語をパクる術を身につけておきましょう!
どれだけRuby文法的にきれいにコードを書いても、命名規則がアレげじゃあ、台無しです。
かっこいいメソッド名を使って、おしゃれRubyにしちゃいましょう。
また、実装自体が短いので、Ruby Wayなコードの書き方の参考にもなるなるです。
(ただし、テストがRSpecじゃないのが残念!)
RDocを見て、気になるメソッドがあればソースもぜひ覗いてください。
今夜さっそく気になるあの子を落とすのに役立つトリビアが待ってるかもしれません。
最後に、、、個人的な趣味で、コード例にPython的な用語を盗用してしまってごめんなさい。
* 一万人の第九!
Posted on December 13th, 2009 by tomoya. Filed under 行った.
12月5日6日に大阪に戻り、「一万人の第九」コンサートに参加してきました。広い大阪城ホールの中に、一万人の歌声が響いたのを聞いたときは、本当に感動的でした。
「一万人の第九」イベントは、その名の通り一万人の大合唱団でベートーヴェンの交響曲第九番を歌おうというイベントで、毎年、年末に開かれています。今年でもう27回目だそうで、知る人ぞ知る年末の恒例イベントです。
合唱隊として参加することを決めたのは今年の夏。妻に誘われて応募してみたら、見事抽選を合格し、東京クラスのレッスンを受けることができることになりました。当選して喜んでは見たものの、ぼくは合唱なんてこれまで一度も参加したことがありません。歌が上手とはお世辞にも言えないし、歌詞であるドイツ語もいっさいわかりません。まったくずぶの素人が参加したわけです。
Pages
Categories
Archives
- June 2010 (1)
- May 2010 (1)
- January 2010 (2)
- December 2009 (2)
- September 2009 (1)
- August 2009 (3)
- July 2009 (3)
- June 2009 (10)
- March 2009 (3)
- February 2009 (9)
- January 2009 (7)





