एक उदाहरण चर का मान प्राप्त करें जिसका नाम दिया गया है


99

सामान्य तौर पर, मैं किसी ऑब्जेक्ट का संदर्भ कैसे प्राप्त कर सकता हूं जिसका नाम मेरे पास एक स्ट्रिंग में है?

विशेष रूप से, मेरे पास पैरामीटर नामों की एक सूची है (सदस्य चर - गतिशील रूप से निर्मित इसलिए मैं उन्हें सीधे संदर्भित नहीं कर सकता)।

प्रत्येक पैरामीटर एक ऑब्जेक्ट है जिसमें एक from_sविधि भी है ।

मैं निम्नलिखित की तरह कुछ करना चाहता हूं (जो निश्चित रूप से काम नहीं करता है ...):

define_method(:from_s) do | arg |
    @ordered_parameter_names.each do | param |
        instance_eval "field_ref = @#{param}"
        field_ref.from_s(param)
    end
end

जवाबों:


179

इसे प्राप्त करने का सबसे मुहावरेदार तरीका है:

some_object.instance_variable_get("@#{name}")

उपयोग करने की आवश्यकता नहीं है +या intern; रूबी यह ठीक से संभाल लेंगे। हालाँकि, यदि आप अपने आप को किसी अन्य वस्तु तक पहुँचते हैं और इसके आइवर को बाहर निकालते हैं, तो एक बहुत अच्छा मौका है कि आपने इनकैप्सुलेशन को तोड़ दिया है।

यदि आप स्पष्ट रूप से एक आइवर का उपयोग करना चाहते हैं, तो ऐसा करने के लिए सही बात यह है कि यह एक एक्सेसर है। निम्नलिखित को धयान मे रखते हुए:

class Computer
  def new(cpus)
    @cpus = cpus
  end
end

इस मामले में, यदि आपने किया, तो आपको प्राप्त Computer.newकरने के लिए उपयोग instance_variable_getकरने के लिए मजबूर किया जाएगा @cpus। लेकिन अगर आप ऐसा कर रहे हैं, तो आप शायद @cpusसार्वजनिक होने के लिए हैं। आपको क्या करना चाहिए:

class Computer
  attr_reader :cpus
end

अब आप कर सकते हैं Computer.new(4).cpus

ध्यान दें कि आप किसी भी मौजूदा वर्ग को फिर से खोल सकते हैं और एक पाठक में एक निजी आइवर बना सकते हैं । चूंकि एक एक्सेसर सिर्फ एक विधि है, आप कर सकते हैंComputer.new(4).send(var_that_evaluates_to_cpus)


क्या आवृत्ति_वर्णीय_गेट ("@ # {नाम}") चर का मान नहीं लौटाता है? मुझे वास्तविक वस्तु के संदर्भ की आवश्यकता है। मैंने कई वेरिएबल्स + के बजाय एक पुनर्लेखन को समाप्त कर दिया, जिसमें मैं चाहता था कि नामों के साथ एक सरणी है, मैंने खुद को मापदंडों को सरणी में डाल दिया (डिजाइन निर्णय यह था कि क्या प्रत्येक बार चर की खोज करके चर का उपयोग करें या एक सरणी होने से ऑप्टिमाइज़ करें। उनके नाम के साथ अतिरिक्त सरणी जो केवल जरूरत पड़ने पर उपयोग की जाएगी)
LK__

नहींं: inst_variable_get ("@ # {{name}") वास्तविक ऑब्जेक्ट देता है।
येहुदा काट्ज़

थोड़ी सी स्पष्टता के लिए मृत धागे को उजागर करना। पूरा उदाहरण होगा: वर्ग कंप्यूटर attr_read: cpus def new (cpus) @cpus = cpus end अंत?
निकोलस डी फोंटेने

"हालांकि, यदि आप अपने आप को किसी अन्य वस्तु में पहुंचते हैं और इसके आइवर को बाहर निकालते हैं, तो एक बहुत अच्छा मौका है कि आपने इनकैप्सुलेशन को तोड़ दिया है।" हम किसी अन्य वस्तु के आइवर में कैसे टूटते हैं?
RubyMiner

9

उदाहरण चर के नाम से एक आवृत्ति चर प्राप्त करने के लिए:

name = "paramName"
instance_variable_get(("@" + name).intern)

यह आवृत्ति चर का मान लौटाएगा @paramName


गतिशील रूप से एक वर्ग बनाते समय, मेरे पास उदाहरण चर नामों की एक सरणी होती है (मुझे इस सूची की आवश्यकता है क्योंकि मुझे उन्हें एक निश्चित क्रम में संभालने की आवश्यकता है)। इस नाम का उपयोग करके, मैं चर का संदर्भ प्राप्त करना चाहता हूं।
LK__

1
मेरे पास एक स्ट्रिंग "परमनाम" है और @paramName के संदर्भ की आवश्यकता है
LK__

1
ठीक है। मेरा सुझाव है कि आप अपने प्रश्न को उन दो टिप्पणियों को कहने के लिए संपादित करें।
डैनियल ल्यूक्राफ्ट

2
इसके अलावा, यह deserialization के साथ कुछ नहीं मिला है। एक बेहतर शीर्षक हो सकता है "अपने नाम को दिए गए एक उदाहरण चर का मूल्य प्राप्त करें" या कुछ और।
डैनियल ल्यूक्राफ्ट

आप हमेशा एक मॉड्यूल :attr_reader varnameकर सकते हैं और जोड़ सकते हैं ताकि आप एक स्वच्छ, कम क्रियात्मक तरीके से चर का उपयोग कर सकें।
ओसोडो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.