希望するメソッドのシグネチャを知っているので、method_missing
の代わりに定義するほうがよい場合があります。あなたは(あなたのクラス定義内の)そのようにそれを行うことができます。
[:bill_date, :registration_date, :some_other_date].each do |attr|
define_method("#{attr}_human") do
(send(attr) || Date.today).strftime('%b %d, %Y')
end
define_method("#{attr}_human=") do |date_string|
self.send "#{attr}=", Date.strptime(date_string, '%b %d, %Y')
end
end
すべての日付の属性を一覧表示することは、あなたがmethod_missing
内部の定期的な方法の代わりに、いくつかの魔法を扱っているように、このアプローチが優れている問題ではない場合。
あなたは(あなたのクラス定義内で)そのようにそれらを取得することができ_date
で終わる名前を持つすべての属性にそれを適用する場合:
column_names.grep(/_date$/)
そして、ここではmethod_missing
溶液(テストしていない、以前かかわらずです1)は、いずれかのテストされていません。
def method_missing(method_name, *args, &block)
# delegate to superclass if you're not handling that method_name
return super unless /^(.*)_date(=?)/ =~ method_name
# after match we have attribute name in $1 captured group and '' or '=' in $2
if $2.blank?
(send($1) || Date.today).strftime('%b %d, %Y')
else
self.send "#{$1}=", Date.strptime(args[0], '%b %d, %Y')
end
end
また、それはあなたがインサイドハンドルこと、respond_to?
メソッドをオーバーライドし、メソッド名のためtrue
を返すようにうれしいです(1.9では代わりにrespond_to_missing?
を上書きする必要があります)。
'method_missing'はあなたが取るべき最後のわらについてです。実際に定義されたメソッドははるかにクリーンで、明確な分離を伴うより良いコード設計につながり、理解しやすく、高速になります。したがって、メソッドを定義できる場合は、常にそれを実行する必要があります。 –
KL-7から学んだように、method_missingより優れたアプローチがありますが、このモデルには4つの異なる日付属性があると考えて、それぞれを手動で定義することは解決策ではありません。 DRY – tybro0103
さて、ここではKL-7の方法が実際に好ましい方法です。彼は私の意図したことを正確に提案しているので、メソッドを定義します。 –