रेल्स माड्यूल में मेटर_कैसेर क्या है?


107

मैं वास्तव में रेल दस्तावेज में यह लगता है नहीं कर सका, लेकिन यह की तरह लगता है 'mattr_accessor' है मॉड्यूल के लिए परिणाम 'attr_accessor' एक सामान्य रूबी में (गेटर और सेटर) वर्ग

उदाहरण के लिए। एक कक्षा में

class User
  attr_accessor :name

  def set_fullname
    @name = "#{self.first_name} #{self.last_name}"
  end
end

उदाहरण के लिए। एक मॉड्यूल में

module Authentication
  mattr_accessor :current_user

  def login
    @current_user = session[:user_id] || nil
  end
end

यह सहायक विधि ActiveSupport द्वारा प्रदान की गई है ।

जवाबों:


181

रेल रूबी mattr_accessor(मॉड्यूल एक्सेसर) और cattr_accessor(साथ ही _ reader/ _writerसंस्करण) दोनों के साथ फैली हुई है । रूबी के रूप में attr_accessorउत्पन्न करता है के लिए गेटर / सेटर तरीकों उदाहरणों , cattr/mattr_accessorपर गेटर / सेटर तरीकों प्रदान वर्ग या मॉड्यूल स्तर। इस प्रकार:

module Config
  mattr_accessor :hostname
  mattr_accessor :admin_email
end

इसके लिए छोटा है:

module Config
  def self.hostname
    @hostname
  end
  def self.hostname=(hostname)
    @hostname = hostname
  end
  def self.admin_email
    @admin_email
  end
  def self.admin_email=(admin_email)
    @admin_email = admin_email
  end
end

दोनों संस्करण आपको मॉड्यूल-स्तरीय चर का उपयोग करने की अनुमति देते हैं जैसे:

>> Config.hostname = "example.com"
>> Config.admin_email = "admin@example.com"
>> Config.hostname # => "example.com"
>> Config.admin_email # => "admin@example.com"

1
आपके उदाहरणों में, आप समझाते हैं कि mattr_accessorकक्षा के उदाहरण चर (चरों @variable) के लिए कम होंगे , लेकिन स्रोत कोड से पता चलता है कि वे वास्तव में कक्षा चर की स्थापना / रीडिंग कर रहे हैं। क्या आप इस अंतर को समझा सकते हैं?
सैंड्रे

38

यहाँ के लिए स्रोत है cattr_accessor

तथा

यहाँ के लिए स्रोत है mattr_accessor

जैसा कि आप देख सकते हैं, वे बहुत अधिक समान हैं।

क्यों दो अलग-अलग संस्करण हैं? कभी-कभी आप cattr_accessorएक मॉड्यूल में लिखना चाहते हैं , इसलिए आप इसका उपयोग अवधी उल्लेखों जैसी कॉन्फ़िगरेशन जानकारी के लिए कर सकते हैं ।
हालांकि, cattr_accessorएक मॉड्यूल में काम नहीं करता है, इसलिए उन्होंने कम या ज्यादा कोड को मॉड्यूल के लिए भी काम करने के लिए कॉपी किया है।

इसके अतिरिक्त, कभी-कभी आप किसी मॉड्यूल में एक वर्ग विधि लिखना चाहते हैं, जैसे कि जब भी किसी भी वर्ग में मॉड्यूल शामिल होता है, तो वह उस क्लास पद्धति के साथ-साथ सभी इंस्टेंस विधियों को भी प्राप्त करता है। mattr_accessorआपको यह करने देता है।

हालांकि, दूसरे परिदृश्य में, यह व्यवहार बहुत अजीब है। निम्नलिखित कोड को ध्यान से देखें, विशेष रूप से @@mattr_in_moduleबिट्स पर ध्यान दें

module MyModule
  mattr_accessor :mattr_in_module
end

class MyClass
  include MyModule
  def self.get_mattr; @@mattr_in_module; end # directly access the class variable
end

MyModule.mattr_in_module = 'foo' # set it on the module
=> "foo"

MyClass.get_mattr # get it out of the class
=> "foo"

class SecondClass
  include MyModule
  def self.get_mattr; @@mattr_in_module; end # again directly access the class variable in a different class
end

SecondClass.get_mattr # get it out of the OTHER class
=> "foo"

यह एक ऐसा गोच था, जो मुझे डिफ़ॉल्ट रूप से सेट करते समय बहुत मुश्किल होता था, सीधे (एक मैटर_कैशर)। एक बार क्लास उन्हें एक तरह से सेट कर देगा और दूसरा उन्हें अलग तरीके से सेट करेगा, इस प्रकार अमान्य लिंक बनाए जाएंगे।
एरिक डेविस

रेल के नवीनतम संस्करण में cattr_*अब उपनाम हैं mattr_*cattr_accessorस्रोत
ouranos
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.