वहाँ एक वर्ग विधि के लिए एक alias_method है?


10

निम्नलिखित वर्ग पर विचार करें:

class Foo
  def an_inst_method
    'instance method'
  end

  def self.a_class_method
    'class method'
  end

  alias_method :a_new_inst_method, :an_inst_method
end

यह कोई समस्या नहीं है और आप Foo.new.a_new_inst_methodबिना किसी समस्या के कॉल कर सकते हैं ।

मैं एक क्लास मेथड को पसंद करने की क्षमता रखता हूं Foo.add_widget(*items)और इसे उर्फ ​​करना चाहता हूं ताकि मैं कुछ ऐसा कर सकूं:

Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'

तो अनिवार्य रूप से यह एक "रूबी शैली" की तरह है 1.minuteऔर 2.minutesइसलिए मैं उर्फ कॉल करना चाहता हूं Foo.add_widgetताकि एक ही कॉलिंग Foo.add_widgetsसटीक विधि हो। मुझे पता है कि मैं इसे लपेट सकता हूं लेकिन मुझे लगता है कि मुझे एक क्लीनर फैशन में ऐसा करने में सक्षम होना चाहिए।

कुछ इस तरह की कोशिश में मेरे प्रयास पर विचार करें:

class Foo
  def an_inst_method
    'instance method'
  end

  def self.a_class_method
    'class method'
  end

  alias_method :a_new_inst_method, :an_inst_method
  alias_method :a_new_class_method, :a_class_method
end

हालाँकि, मुझे निम्न त्रुटि मिलती है:

NameError (undefined method `a_class_method' for class `Foo')

और इसलिए ऐसा लगता है कि यह क्लास के तरीकों के लिए काम नहीं करता है। मैं यह कार्य कैसे करूं?

जवाबों:


9

alias_methodरिसीवर के एक उदाहरण विधि उपनाम। क्लास के तरीके वास्तव में एक क्लास के सिंगलटन क्लास पर परिभाषित उदाहरण के तरीके हैं ।

class MyClass
  def self.a
    "Hello World!"
  end
end

method_1 = MyClass.method(:a).unbind
method_2 = MyClass.singleton_class.instance_method(:a)

method_1 == method_2
#=> true

एकल वर्ग को परिभाषित करने के लिए एकल वर्ग को परिभाषित करने के लिए आप या तो इसे class << objectसिंटैक्स का उपयोग करके खोल सकते हैं ।

class << MyClass
  alias_method :b, :a
end

MyClass.b
#=> "Hello World!"

या आप सीधे singleton_classविधि का उपयोग करके इसे संदर्भित कर सकते हैं ।

MyClass.singleton_class.alias_method :c, :a

MyClass.c
#=> "Hello World!"

यदि आप अभी भी वर्ग के संदर्भ में हैं तो कक्षा selfको संदर्भित करेंगे। तो ऊपर भी लिखा जा सकता है:

class MyClass
  class << self
    def a
      "Hello World!"
    end
    alias_method :b, :a
  end
end

या

class MyClass
  def self.a
    "Hello World!"
  end
  singleton_class.alias_method :c, :a
end

या दो का एक संयोजन।


5

आप वर्ग विधियों और उनकी alias_methodकॉल को एक अलग मॉड्यूल में लपेट सकते हैं और उस मॉड्यूल को अपनी कक्षा में शामिल कर सकते हैं extend:

class Foo
  def an_inst_method
    'instance method'
  end
  alias_method :a_new_inst_method, :an_inst_method

  module ClassMethods
    def a_class_method
      'class method'
    end
    alias_method :a_new_class_method, :a_class_method
  end

  extend ClassMethods
end

अरे! मैं extend ClassMethodsसमाधान के बारे में भूल गया । +1
अरोना

4

समझने की महत्वपूर्ण बात यह है कि रूबी में क्लास पद्धति जैसी कोई चीज नहीं है

एक वर्ग विधि वास्तव में सिर्फ एक एकल विधि है। क्लास के तरीकों के बारे में कुछ खास नहीं है। हर ऑब्जेक्ट में सिंगलटन तरीके हो सकते हैं। हम उन्हें "क्लास मेथड्स" कहते हैं, जब ऑब्जेक्ट एक Class"एग्जाम्पल का सिंग्लटन मेथड Class" होता है, वह बहुत लंबा और अलौकिक होता है।

रुको! क्या मैंने कहा "सिंगलटन विधि"?

समझने के लिए एक और महत्वपूर्ण बात यह है कि रूबी में एक सिंगलटन विधि जैसी कोई चीज नहीं है

एक सिंगलटन विधि वास्तव में सिंगलटन क्लास की एक नियमित उबाऊ पुरानी आवृत्ति है। सिंगलटन के तरीकों के बारे में कुछ खास नहीं है। वे किसी भी अन्य उदाहरण विधि की तरह सिर्फ उदाहरण के तरीके हैं।

वास्तव में, रूबी के पास केवल उदाहरण के तरीके हैं। कोई कार्य नहीं, कोई निर्माता नहीं, कोई स्थिर विधियाँ नहीं, कोई वर्ग विधियाँ नहीं, कोई मॉड्यूल कार्य नहीं, कोई एकल पद्धतियाँ नहीं।

सवाल यह नहीं है "क्या यह एक वर्ग विधि है, क्या यह एक एकल पद्धति है", बल्कि यह " इस पद्धति को किस मॉड्यूल में परिभाषित किया गया है?"

"सिंगलटन तरीके" वास्तव में एकलिंग क्लास में परिभाषित उदाहरण विधि हैं। के एकल वर्ग तक पहुँचने के लिए वाक्यविन्यास fooहै

class << foo
end

एक विधि भी है Object#singleton_classजो एक वस्तु के सिंगलटन वर्ग को वापस करती है।

मैं इस तथ्य के बारे में आक्रामक तरीके से क्यों कह रहा हूं कि हर विधि एक उदाहरण विधि है और उस वर्ग के तरीके मौजूद नहीं हैं? क्योंकि इसका मतलब है कि रूबी का ऑब्जेक्ट मॉडल लोगों की तुलना में बहुत सरल है! आखिरकार, आपके प्रश्न में, आप पहले से ही दिखाते हैं कि आप उदाहरणों के तरीकों को अलियास करना जानते हैं, लेकिन आप कहते हैं कि आप क्लास के तरीकों को नहीं जानते हैं। लेकिन, यह गलत है! आप कर क्योंकि, जानते हैं कि कैसे उर्फ वर्ग तरीकों को वे सिर्फ उदाहरण तरीके हैं । यदि आपको इस तथ्य को ठीक से पढ़ाया जाता, तो आपको यह प्रश्न पूछने की आवश्यकता नहीं होती!

एक बार जब आप समझ जाते हैं कि हर विधि एक उदाहरण विधि है, और जिसे हम "सिंगलटन तरीके" कहते हैं, सिंगलटन वर्ग की सिर्फ उदाहरण विधियां हैं, तो समाधान स्पष्ट हो जाता है:

singleton_class.alias_method :a_new_class_method, :a_class_method

नोट: जब मैंने ऊपर लिखा कि "X जैसी कोई चीज नहीं है", तो मेरा मतलब था कि " रूबी भाषा में X जैसी कोई चीज नहीं है "। इसका मतलब यह नहीं है कि रूबी समुदाय में वे अवधारणाएं मौजूद नहीं हैं ।

हम नियमित रूप से, के बारे में "सिंगलटन तरीकों" और "वर्ग तरीकों" बात बस क्योंकि इसके बारे में "सिंगलटन वर्ग के उदाहरण तरीकों" या "किसी वस्तु की सिंगलटन वर्ग जो का एक उदाहरण होने के कहने तरीकों में बात कर की तुलना में आसान है Classवर्ग "। वहाँ की तरह भी तरीके हैं Object#define_singleton_method, Object#singleton_method, Object#singleton_methods, Module#private_class_method, Module#public_class_method, और Module#module_functionमें रूबी कोर पुस्तकालय। लेकिन यह याद रखना हमेशा महत्वपूर्ण है कि वे भाषा की अवधारणा नहीं हैं। वे सामुदायिक अवधारणाएं हैं जो केवल हमारे सिर में और कुछ पुस्तकालय विधियों के नामों में मौजूद हैं ।


2

ठीक है, ऐसा लग रहा है कि मैं ऐसा कुछ कर सकता हूं और यह काम करेगा:

class Foo
  def an_inst_method
    'instance method'
  end

  def self.a_class_method
    'class method'
  end

  alias_method :a_new_inst_method, :an_inst_method

  class << self
    alias_method :a_new_class_method, :a_class_method
  end
end

Foo.a_class_method # => "class method" 
Foo.a_new_class_method # => "class method"

अगर किसी को यहाँ रूबी भाषा के बारे में कोई उपयोगी जानकारी है और वह एक व्यापक उत्तर प्रस्तुत करना चाहेगा, तो मैं आपको +1 दूंगा।


1
जब आप आपके class << selfद्वारा पीछा करते हैं, alias_method :a_new_class_method, :a_class_methodतो वास्तव alias_methodमें सिंगलटन वर्ग पर कॉल करते हैं Foo। इसे लिखने का एक और तरीका है: singleton_class.alias_method :a_new_class_method, :a_class_methodकक्षा के संदर्भ में।
3limin4t0r

आप एक उत्तर से और क्या चाहते हैं? मेरा मतलब है, यह संभवतः सबसे साफ समाधान है।
डेव न्यूटन

@ 3limin4t0r यदि आप इसका उत्तर बनाते हैं, तो मैं इसे +1 करूँगा। इस अतिरिक्त जानकारी के लिए धन्यवाद।
अरोना

@DaveNewton आप सही हैं लेकिन क्योंकि मेरे पास भी एक दर्शन है कि अगर कोई व्यक्ति किसी समस्या को और अधिक सार्थक जानकारी प्रदान कर सकता है, भले ही वह परोक्ष रूप से समस्या का हल करे, मुझे लगता है कि उसे पुरस्कृत भी किया जाना चाहिए।
अरोना

2

alias_methodउदाहरण पर संचालित होता है, इसलिए आपको एक स्तर पर गहराई तक जाने की आवश्यकता है और Classउदाहरण के लिए, या कक्षा के मेटाक्लस का संचालन करना चाहिए । रूबी के पास एक जंगली वस्तु मॉडल है जो मस्तिष्क के टूटने की तरह हो सकता है, लेकिन यह आपको एक टन बिजली भी देता है:

class Foo
  def an_inst_method
    'instance method'
  end

  alias_method :a_new_inst_method, :an_inst_method

  class << self
    def a_class_method
      'class method'
    end

    alias_method :a_new_class_method, :a_class_method
  end
end

मैं लगभग एक दशक से रेल के संदर्भ में माणिक के साथ काम कर रहा हूं लेकिन हाल ही में ऑब्जेक्ट मॉडल में एक गहरा गोता लगाने की शुरुआत की है। वहाँ बहुत अच्छा सामान उपलब्ध है!
अरोना
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.