rubicure
最近ちまちまこっそりコードリーディングをしてる. 自分が普段かかないような構文がみられるのは楽しい.
今回は特に目的を決めないで目についた面白そうなところから読んでみる
rubicure
All about Japanese battle heroine "Pretty Cure (Precure)".
プリキュアのruby実装. ちなみにたこはプリキュアは無印しかしらない.
よんでみる
執筆時点の最新v1.0.4をよむ.
とりあえずreadmeの一番頭を見てみる
Precure.title #=> "ふたりはプリキュア" Precure.unmarked.title #=> "ふたりはプリキュア" Precure.max_heart.title #=> "ふたりはプリキュア Max Heart" # ...
title
メソッドとかは,yamlファイルにかかれたハッシュから引かれてるみたい.(というかキーそれぞれにメソッド生やしてたら必要以上に冗長になりそう)この辺のメソッドを定義してる部分から読んでみる.
unmarked: &unmarked series_name: unmarked title: ふたりはプリキュア started_date: 2004-02-01 ended_date: 2005-01-30 girls: - cure_black - cure_white futari_wa_pretty_cure: <<: *unmarked # ...
Precure
module は method_missing
がオーバーライトされてた.
module Precure def self.method_missing(name, *args, &block) Rubicure.core.send(name, *args, &block) end end
Rubicure.core
で method を実行させているけど,ここでも method_missing
が上書きされていて, Rubicure::Series#find
でハッシュの中身をもってきてる
def method_missing(name, *args) unmarked_precure = Rubicure::Series.find(:unmarked) if Rubicure::Series.valid?(name) Rubicure::Series.find(name) elsif unmarked_precure.respond_to?(name) unmarked_precure.send(name, *args) else super end end
https://github.com/sue445/rubicure/blob/v1.0.4/lib/rubicure/core.rb#L10-L20
config
で yaml をロードしたハッシュを持ってきてる.
https://github.com/sue445/rubicure/blob/master/lib/rubicure/series.rb#L84-L91
def find(series_name) raise UnknownSeriesError, "unknown series: #{series_name}" unless valid?(series_name) @cache ||= {} unless @cache[series_name] series_config = config[series_name] || {} series_config.reject! { |_k, v| v.nil? } @cache[series_name] = Rubicure::Series[series_config] end @cache[series_name] end
method missing のオーバーライドはびっくりした
Cure
もyamlからデータを引っぱってくるところまでは Series
とほぼほぼ同じ
Cure.lemonade #=> {:girl_name=>"cure_lemonade", :human_name=>"春日野うらら", :precure_name=>"キュアレモネード", :cast_name=>"伊瀬茉莉也", :created_date=>Sun, 18 Feb 2007, :color=>"yellow", :transform_message=>"プリキュア!メタモルフォーゼ!\nはじけるレモンの香り、キュアレモネード!\n希望の力と未来の光!\n華麗に羽ばたく5つの心!\nYes!プリキュア5!", :extra_names=>nil, :attack_messages=>["輝く乙女のはじける力、受けてみなさい!\nプリキュア!プリズム・チェーン!"], :transform_calls=>["metamorphose"]} Cure.pine #=> {:girl_name=>"cure_pine", :human_name=>"山吹祈里", :precure_name=>"キュアパイン", :cast_name=>"中川亜紀子", :created_date=>Sun, 15 Feb 2009, :color=>"yellow", :transform_message=>"チェインジ!プリキュア・ビートアップ!\nイエローハートは祈りのしるし!\nとれたてフレッシュ、キュアパイン!\nレッツプリキュア!", :extra_names=>["キュアエンジェルパイン"], :attack_messages=>["悪いの悪いの飛んでいけ!\nプリキュア!ヒーリングプレアーフレッシュ!"], :transform_calls=>["change_precure_beat_up", "change", "beat_up"]} Cure.sunshine #=> {:girl_name=>"cure_sunshine", :human_name=>"明堂院いつき", :precure_name=>"キュアサンシャイン", :cast_name=>"桑島法子", :created_date=>Sun, 18 Jul 2010, :color=>"yellow", :transform_message=>"(プリキュアの種、いくですぅ!)\nプリキュア!オープンマイハート!\n陽の光浴びる一輪の花! キュアサンシャイン!\nハートキャッチ、プリキュア!", :extra_names=>["スーパーキュアサンシャイン"], :attack_messages=>["花よ、舞い踊れ!\nプリキュア!ゴールドフォルテバースト!!", "花よ、咲き誇れ!\nプリキュア・ハートキャッチ・オーケストラ!!"], :transform_calls=>["open_my_heart"]} # ...
だけど,プリキュアは変身すると攻撃できるようになる.
yayoi = Precure.smile.girls[2] yayoi.name #=> "黄瀬やよい" yayoi.cast_name #=> "金元寿子" yayoi.attack! #=> RuntimeError: require transform yayoi.transform! (レディ?) プリキュア・スマイルチャージ! (ゴー!ゴー!レッツ・ゴー!ピース!!) ピカピカピカリンジャンケンポン! キュアピース! 5つの光が導く未来! 輝け!スマイルプリキュア! # 1st transform yayoi.name #=> "キュアピース" yayoi.attack! プリキュア!ピースサンダー!!
def attack! raise RequireTransformError, "require transform" if current_attack_message.blank? print_by_line current_attack_message current_attack_message end
@current_state
って変数に整数値で現在の状態をもたせてた.0だったら変身前,1だったら1段階変身..みたいな. これをcurrent_attack_message
で変身後かどうか(@current_state
が0でないか)を判定して変身の台詞を持ってきてる. print_by_line
はいい感じにdelayをつけてメッセージを標準出力するやつ.
yamlには attack_messages
に台詞が配列で入ってて @current_state
でインデックスを指定できるようになってる.
cure_peace: &cure_peace # ... extra_names: - プリンセスピース - ウルトラピース attack_messages: - |- プリキュア!ピースサンダー!! - |- 開け、ロイヤルクロック! (みんなの力を1つにするクル!) 届け、希望の光! はばたけ!光り輝く未来へ! プリキュア!ロイヤルレインボーバースト! - |- (みんなの力を1つにするクル!) プリキュア!ミラクルレインボーバースト! 輝けー!! スマイルプリキュア!! transform_calls: - smile_charge
raise RequireTransformError, "require transform"
がかっこいい.
lib/rubicure/errors.rb
で定義してる
transform!
, name
もおなじように @current_state
でひっぱってきてる
maho_girls
だけは transform_styles
ってのがあって,それぞれに girl_name
, human_name
... てのがあるらしく,それは define_method
で定義されてた.
https://github.com/sue445/rubicure/blob/v1.0.4/lib/rubicure/girl.rb#L95-L103
まなび
- yamlのloadとか,
|-
記法(配列の最後の改行を無視する)とか include Enumerable
で each メソッドを定義できる https://github.com/sue445/rubicure#enumerablemethod_missing
はインパクトあった.多分しばらくわすれない
かんそう
最新シリーズのアラモードってやつのyamlが美味しそうで夜中に読んでたら無限にお腹がへったのがつらかった.
REF
rubicure: All about Japanese battle heroine "Pretty Cure (Precure)"