आरंभ निम्नलिखित वर्ग को देखते हुए संपत्ति मूल्यों की स्थापना nil
अभी भी। क्या यह संभव है?रूबी जब वस्तु
नोट: मैं प्रारंभकर्ता नहीं जोड़ना चाहता हूं।
आरंभ निम्नलिखित वर्ग को देखते हुए संपत्ति मूल्यों की स्थापना nil
अभी भी। क्या यह संभव है?रूबी जब वस्तु
नोट: मैं प्रारंभकर्ता नहीं जोड़ना चाहता हूं।
जो कोड आप इंगित कर रहे हैं वह initialize
फ़ंक्शन में पैरामीटर पास कर रहा है।
test = Test.new
test.name = 'Some test object'
दूसरों के द्वारा उल्लेख किया है, यह करने के लिए सबसे आसान तरीका है किया जाएगा एक initialize
विधि को परिभाषित करने के: आप सबसे निश्चित रूप से या तो 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"
ठीक है,
मैं एक समाधान के साथ आया था। यह प्रारंभिक विधि का उपयोग करता है लेकिन दूसरी ओर वही करें जो आप चाहते हैं।
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
ध्यान दें कि इस तरह सेकी जटिल परिवर्तन की आवश्यकता नहीं हैविधि (जो वास्तव में, एक-लाइनर है)।
टेस्ट उपवर्ग की जरूरत है सकते हैं (यहाँ खुद विधि और प्रारंभकर्ता साथ दिखाया गया है) उदा .:
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
विधि के माध्यम से आवश्यक सभी आवृत्ति चर पारित कर सकते हैं और इसे गेटर्स और सेटर्स को परिभाषित करने के अलावा उन्हें बनाने दें।
यदि आप 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
आखिरी बात आप में पारित एक हैश यह initialize
बाईपास और setters तुरंत फोन जाएगा। यदि आप इसमें कुछ और पास करते हैं तो उन तर्कों के साथ आरंभ करने के लिए कॉल करेंगे।
जैसा कि पहले उल्लेख किया गया था, ऐसा करने का समझदार तरीका या तो Struct
या Test#initialize
विधि को परिभाषित करके है। यह वही है जो structs और रचनाकारों के लिए हैं। गुण के लिए इसी एक विकल्प हैश का उपयोग कर अपने सी # उदाहरण के निकटतम बराबर है, और यह एक सामान्य दिखने रूबी सम्मेलन है:
t = Test.new({:name => "something"})
t = Test.new(name: "something") # json-style or kwargs
लेकिन अपने उदाहरण में आप कुछ है कि अधिक चर काम की तरह लग रहा =
का उपयोग कर तो चलो चलो कर रहे हैं हैश के बजाय ब्लॉक का उपयोग करने का प्रयास करें। (आप भी Name
उपयोग कर रहे हैं जो रूबी में एक निरंतर हो सकता है, हम चाहते हैं कि बदल देंगे।)
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
नहीं हैं,) है एक बहुत ही विशिष्ट और मनोरंजक अनुरोध के लिए एक रचनात्मक समाधान।
प्रारंभिक विधि को हल करना (क्या आपका मतलब है?) चीजों को मुश्किल बनाता है। नई 'टेस्ट' ऑब्जेक्ट्स बनाते समय, 'नाम' को प्रत्येक बार समान प्रारंभिकता प्राप्त करनी चाहिए? या इसे ओपन कोड में निर्दिष्ट मान प्राप्त करना चाहिए? – DigitalRoss
प्रेरणा सी # के समान कुछ करना होगा - http://msdn.microsoft.com/en-us/library/bb384062.aspx –
क्या ऐसा कुछ है जिसे आप प्रस्तावित समाधान के साथ पसंद नहीं करते हैं? –