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


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.