紅寶石初始化對象
回答
您正在指示的代碼將參數傳遞給initialize
函數。你肯定會必須要麼使用initialize
,或使用更無聊的語法:
test = Test.new
test.name = 'Some test object'
正如其他人所提到的,要做到這一點最簡單的方法是定義一個initialize
方法。如果你不想這樣做,你可以讓你的課程繼承Struct。
class Test < Struct.new(:name)
end
所以現在:
>> t = Test.new("Some Test Object")
=> #<struct Test name="Some Test Object">
>> t.name
=> "Some Test Object"
OK,
我想出了一個解決方案。它使用初始化方法,但另一方面完全按照你想要的。
class Test
attr_accessor :name
def initialize(init)
init.each_pair do |key, val|
instance_variable_set('@' + key.to_s, val)
end
end
def display
puts @name
end
end
t = Test.new :name => 'hello'
t.display
高興嗎? :)
使用繼承的替代解決方案。請注意,使用此解決方案,您不需要顯式聲明attr_accessor!
class CSharpStyle
def initialize(init)
init.each_pair do |key, val|
instance_variable_set('@' + key.to_s, val)
instance_eval "class << self; attr_accessor :#{key.to_s}; end"
end
end
end
class Test < CSharpStyle
def initialize(arg1, arg2, *init)
super(init.last)
end
end
t = Test.new 'a val 1', 'a val 2', {:left => 'gauche', :right => 'droite'}
puts "#{t.left} <=> #{t.right}"
有一種通用的方法來完成複雜的對象初始化 - 通過必要的動作傳遞塊。該塊可在該對象的上下文進行評估,所以你可以很方便地訪問所有的實例變量,方法等
繼續你的榜樣
class Test
attr_accessor :name
def initialize(&block)
instance_eval(&block)
end
end
然後
t = Test.new { @name = 'name' }
或
t = Test.new do
self.name = 'name'
# other initialization, if needed
end
請注意,這種方式並不需要複雜的initialize
方法(實際上是單線)。
會需要繼承測試(在這裏與自己的方法和初始化所示)例如爲:
class Test
attr_accessor :name, :some_var
def initialize some_var
@some_var = some_var
end
def some_function
"#{some_var} calculation by #{name}"
end
end
class SubClassedTest < Test
def initialize some_var, attrbs
attrbs.each_pair do |k,v|
instance_variable_set('@' + k.to_s, v)
end
super(some_var)
end
end
tester = SubClassedTest.new "some", name: "james"
puts tester.some_function
輸出:some calculation by james
你能做到這一點。
class Test
def not_called_initialize(but_act_like_one)
but_act_like_one.each_pair do |variable,value|
instance_variable_set('@' + variable.to_s, value)
class << self
self
end.class_eval do
attr_accessor variable
end
end
end
end
(t = Test.new).not_called_initialize :name => "Ashish", :age => 33
puts t.name #=> Ashish
puts t.age #=> 33
一個優點是,你甚至不必使用attr_accessor
來定義實例變量的前期。您可以通過not_called_initialize
方法傳遞所需的所有實例變量,並讓它創建它們,除了定義getter和setter。
如果您不想覆蓋initialize
,那麼您必須向上移動並覆蓋new
。這裏有一個例子:
class Foo
attr_accessor :bar, :baz
def self.new(*args, &block)
allocate.tap do |instance|
if args.last.is_a?(Hash)
args.last.each_pair do |k,v|
instance.send "#{k}=", v
end
else
instance.send :initialize, *args
end
end
end
def initialize(*args)
puts "initialize called with #{args}"
end
end
如果您傳遞的最後一件事是一個Hash它會繞過initialize
,並立即撥打製定者。如果你傳遞了其他的東西,它會調用這些參數初始化。
如前所述,明智的做法是使用Struct
或定義Test#initialize
方法。這正是結構和構造函數的用途。使用對應屬性的選項哈希是你的C#示例的最接近的,這是一個正常的前瞻性的Ruby約定:
t = Test.new({:name => "something"})
t = Test.new(name: "something") # json-style or kwargs
但在你的例子中,你正在做的事情用=
讓我們看起來更象變量賦值嘗試使用塊而不是散列。 (您還使用Name
這將是Ruby的一個常量,我們將改變這一現狀。)
t = Test.new { @name = "something" }
酷,現在讓我們實際工作:
class BlockInit
def self.new(&block)
super.tap { |obj| obj.instance_eval &block }
end
end
class Test < BlockInit
attr_accessor :name
end
t = Test.new { @name = "something" }
# => #<Test:0x007f90d38bacc0 @name="something">
t.name
# => "something"
我們已經創建了一個該類使用構造函數接受一個塊參數,該參數在新實例化的對象中執行。
因爲你說過要避免使用initialize
,所以我將覆蓋new
並呼籲super
從Object#new
獲取默認行爲。 通常我們會定義initialize
而不是,除了滿足您的問題中的特定請求外,不建議使用此方法。
當我們將塊傳遞給BlockInit
的子類時,我們可以做的不僅僅是設置變量......我們基本上只是將代碼注入initialize
方法(我們正在避免編寫)。如果您還想要一個initialize
方法,做其他的東西(如你在評論中提到的),你可以把它添加到Test
,甚至不用調用super
(因爲我們的改變是不BlockInit#initialize
,而BlockInit.new
)
希望這一個非常具體和有趣的請求的創造性解決方案。
- 1. 初始化紅寶石
- 2. 紅寶石/黃瓜測試初始化
- 3. 紅寶石類的計數初始化
- 4. 初始化紅寶石散列問題
- 5. 紅寶石初始化和自我
- 6. 紅寶石未初始化不斷
- 7. 紅寶石自我。 vs @初始化
- 8. 紅寶石未初始化的常量
- 9. 紅寶石 - 未初始化的常量
- 10. 紅寶石,未初始化不斷
- 11. 「在初始化塊」未初始化不斷Testdeck NameError(紅寶石)
- 12. 未初始化的常量使用Twitter的紅寶石寶石
- 13. 紅寶石寶石devise無法生成初始化程序
- 14. 紅寶石的SoundCloud寶石:未初始化不斷的SoundCloud
- 15. 紅寶石哈希初始值設定
- 16. 紅寶石比較對象
- 17. 從對象紅寶石
- 18. 紅寶石和零對象
- 19. 紅寶石顯示對象
- 20. 紅寶石修改對象
- 21. 紅寶石寶石加載,但依然給人「未初始化的常量」
- 22. 紅寶石初始化實例變量以外的方法
- 23. 紅寶石2.1+關鍵參數初始化器語法
- 24. 紅寶石未初始化不斷的RecipesController ::食譜
- 25. 紅寶石:質量初始化實例變量
- 26. NameError:未初始化的常量歌...編程紅寶石
- 27. 紅寶石元編程:初始化變量singleton_class
- 28. 初始化類的成員變量失去價值紅寶石
- 29. 如何初始化三維紅寶石陣列
- 30. 紅寶石:打電話給別人之前初始化方法
排除初始化方法(這是你的意思?)使事情變得困難。在創建新的'Test'對象時,'name'是否每次都得到相同的初始化?還是應該得到在開放代碼中指定的值? – DigitalRoss
的動機是做類似於C#的東西 - http://msdn.microsoft.com/en-us/library/bb384062.aspx –
有什麼你不喜歡與我提出的解決方案? –