2012-01-28 8 views
6

मैं तिथि का उप-वर्ग बनाना चाहता हूं।दिनांक क्यों नहीं है। नया प्रारंभ नहीं है?

एक सामान्य, स्वस्थ, युवा rubyist, दिनांक के कार्यान्वयन निम्नलिखित तरीके से इस बारे में जाना होगा की लत से unscarred:

require 'date' 

class MyDate < Date 

    def initialize(year, month, day) 
    @original_month = month 
    @original_day = day 

    # Christmas comes early! 
    super(year, 12, 25) 
    end 

end 

और सबसे उम्मीद ढंग से इसका इस्तेमाल करने के लिए आगे बढ़ें ...

require 'my_date' 

mdt = MyDate.new(2012, 1, 28) 

puts mdt.to_s 

... केवल डबल-पार तथ्य से हो सकता है, कि दिनांक :: नई विधि वास्तव में आज तक किसी अन्य नाम :: नागरिक है, जो कभी नहीं कॉल इनिशियलाइज़ करता है। इस मामले में, "2012-12-25" अपेक्षित के बजाय कोड का अंतिम भाग "2012-01-28" प्रिंट करता है।

प्रिय रूबी-समुदाय, wtf यह है?

वहाँ नई aliasing के लिए कुछ बहुत अच्छे कारण है, इतना है कि यह ध्यान नहीं देता प्रारंभ, और एक परिणाम के रूप में, किसी भी सामान्य ज्ञान और ग्राहक के प्रोग्रामर के मानसिक स्वास्थ्य के लिए संबंध?

+1

करके जिसका "अच्छा" की परिभाषा? –

+0

विकल्प क्या है? यदि आप प्रारंभिक से नागरिक को कॉल करते हैं, तो आपने उस ऑब्जेक्ट को आवंटित किया है जिसकी आपको आवश्यकता नहीं है। – pguardiario

+0

ठीक है, यह एक ही विधि में ऑब्जेक्ट आवंटित करने और आरंभ करने के लिए अर्थात् गलत रूप से गलत लगता है। मेरा मतलब है, अगर 'नागरिक' वास्तविक रूप से 'नया' है, तो अंत में इसे 'प्रारंभिक' क्यों न करें? यह 'तिथि' में शुद्ध औपचारिकता हो सकती है, लेकिन यह वास्तव में इसके कार्यान्वयन विवरणों के माध्यम से खोदने की आवश्यकता के बिना कक्षा का विस्तार करने की अनुमति देगी। इसलिए, मैंने सोचा, क्यों 'नागरिक' को 'नया' करने का निर्णय लिया जा सकता था? – jst

उत्तर

6

आप initialize परिभाषित करते हैं, लेकिन आप new के साथ नया उदाहरण बनाते हैं। new कक्षा का एक नया उदाहरण देता है, न कि initialize का परिणाम।

आप ऐसा कर सकते हैं:

require 'date' 

class MyDate < Date 

    def self.new(year, month, day) 
    @original_month = month 
    @original_day = day 

    # Christmas comes early! 
    super(year, 12, 25) 
    end 

end 

mdt = MyDate.new(2012, 1, 28) 

puts mdt.to_s 

टिप्पणी: @original_month और @original_day इस समाधान में उपलब्ध नहीं हैं। निम्नलिखित समाधान तिथि बढ़ाता है, ताकि आप मूल माह और दिन तक पहुंच सकें। सामान्य तिथियों के लिए, मूल्य शून्य होंगे।

require 'date' 

class Date 
    attr_accessor :original_month 
    attr_accessor :original_day 
end 

class MyDate < Date 

    def self.new(year, month, day) 

    # Christmas comes early! 
    date = super(year, 12, 25) 
    date.original_month = month 
    date.original_day = day 
    date 
    end 

end 

mdt = MyDate.new(2012, 1, 28) 

puts mdt.to_s 
puts mdt.original_month 

लेकिन मैं सिफारिश करेंगे:

require 'date' 

class MyDate < Date 

    def self.create(year, month, day) 
    @original_month = month 
    @original_day = day 

    # Christmas comes early! 
    new(year, 12, 25) 
    end 

end 

mdt = MyDate.create(2012, 1, 28) 

puts mdt.to_s 

या

require 'date' 

class Date 

    def this_year_christmas 
    # Christmas comes early! 
    self.class.new(year, 12, 28) 
    end 

end 

mdt = Date.new(2012, 1, 28).this_year_christmas 

puts mdt.to_s 
+0

महान उत्तर के लिए धन्यवाद! मैंने 'नई' विधि को अधिभारित कर दिया। यह बहुत अजीब लगता है कि वस्तु का आवंटन और प्रारंभिकरण एक विधि में होता है। – jst

+0

अपनी 'self.create' परिभाषा में, उदाहरण के संस्करणों को उदाहरण पर नहीं, कक्षा पर सेट किया जा रहा है। 'New' के परिणाम पर' instance_variable_set' का उपयोग करना उस पर ध्यान रखेगा; बस सुनिश्चित करें कि आप अभी भी उदाहरण वापस कर दें। – Kelvin

संबंधित मुद्दे