我有很多這樣的方法在視圖助手製法方法:簡單的Ruby元編程
def background
"#e9eaec"
end
def footer_link_color
"#836448"
end
我想這些方法容易看到,但我更喜歡的幫手是一個一點更簡潔。將哈希變成方法(或其他方法)的最佳方式是什麼?
我有很多這樣的方法在視圖助手製法方法:簡單的Ruby元編程
def background
"#e9eaec"
end
def footer_link_color
"#836448"
end
我想這些方法容易看到,但我更喜歡的幫手是一個一點更簡潔。將哈希變成方法(或其他方法)的最佳方式是什麼?
module MyHelper
{:background => "#e9eaec", :footer_link_color => "#836448"}.each do |k,v|
define_method(k) {v}
end
end
雖然我不認爲交易這一點簡潔爲您的第一種方法的可讀性是一個好主意。
如果要概括這一點,你可以在下面的方法添加到模塊類:
class Module
def methods_from_hash(hash)
hash.each do |k,v|
define_method(k) {v}
end
end
end
,然後在助手呼籲methods_from_hash(:background => ...)
。
如果你在一個命名空間創建常量,那麼你馬上就能存取這些常數:
class Foo
module Values
FOO = 1
BAR = 'bar'
BAZ = :baz
end
include Values
Values.constants.each do |name|
define_method(name.downcase) do
Values.const_get(name)
end
end
end
foo = Foo.new
p foo.foo # => 1
p foo.bar # => "bar"
p foo.baz # => :baz
的include Values
混合常數爲富爲Foo的自己的方法的便利。這種模式不需要工作。
Ruby知道他們是常量,或者僅僅是一個約定? – 2010-05-17 22:43:30
@yar,Ruby知道我們正在定義一個常量,因爲標識符以大寫字母開頭。它如何跟蹤什麼是常數,什麼不是,我不知道。 – 2010-05-17 22:51:05
對於Ruby來說,這是一個令人啼笑皆非的悲哀事實:它很多都是用非Ruby編寫的,除非你想進入C語言之下,否則很難知道所有這些東西。感謝您的回答。 – 2010-05-18 00:02:02
這是我sepp2k答案的混音。這是一個更多的面向對象和工作,即使在irb
。不知道是否補丁Object
或Hash
。
class Hash
def keys_to_methods()
each do |k,v|
self.class.send(:define_method, k, Proc.new {v});
end
length
end
end
測試代碼
hash = {:color_one=>"black", :color_two=>"green"}
hash.keys_to_methods
has.color_one # returns black
OpenStruct:感謝再次sepp2k!我不知道this存在。
這裏尚未使用的method_missing
class Hash
def method_missing(method_id)
key = method_id.id2name
if has_key?(key)
return self[key]
elsif has_key?(key.to_sym)
return self[key.to_sym]
else
super.method_missing(method_id)
end
end
end
hash = {:color_one=>"black", :color_two=>"green"}
hash.color_one
我相信我能得到的代碼更嚴格的另一個版本(如果我知道如何)。
修補對象沒有任何意義,因爲這隻會對至少具有每種方法的對象起作用(所以至少Enumerable)。還要注意,如果你想要的只是一個散列,你可以通過使用'hash.key'而不是'hash [key]'來獲得key的值,你可以使用OpenStruct(或者使用'method_missing' )。 – sepp2k 2010-05-22 10:55:06
謝謝@ sepp2k,我用method_missing實現,但我不知道如何優雅地處理鍵符號或字符串。 – 2010-05-23 08:26:15
實際上,ruby有一些叫做OpenStruct的東西,這對於想要散列但不想像一個散列時使用它非常棒和真正有用。
require 'ostruct'
colors = OpenStruct.new({:background => "0x00FF00", :color => "0xFF00FF"})
p colors.background #=> "0x00FF00"
感謝vava,昨天我瞭解到了這一點,這要感謝sepp2k對我的回答(在某處)的評論。 – 2010-05-23 09:15:30
實際上,如果您將散列和猴子補丁用於模塊類,它會更乾淨。我挺喜歡它的。謝謝。 – 2010-05-18 01:57:13
我在下面的「答案」中重新混合了你的答案......雖然我需要弄清楚在原始問題(幫助者)的上下文中哪個版本更好。 – 2010-05-22 08:31:12