खोज…


परिचय

मेटाप्रोग्रामिंग को दो तरीकों से वर्णित किया जा सकता है:

"कंप्यूटर प्रोग्राम जो अन्य प्रोग्राम (या स्वयं) को अपने डेटा के रूप में लिखते हैं या उनमें हेरफेर करते हैं, या जो संकलन समय पर काम करते हैं, जो अन्यथा रनटाइम पर किया जाएगा"।

अधिक सीधे शब्दों में कहें: मेटाप्रोग्रामिंग कोड लिख रहा है जो आपके जीवन को आसान बनाने के लिए रनटाइम के दौरान कोड लिखता है

उदाहरण मूल्यांकन का उपयोग करके "के साथ" को लागू करना

कई भाषाओं में एक बयान के with सुविधा होती है जो प्रोग्रामर को विधि कॉल के रिसीवर को छोड़ देने की अनुमति देता है।

with आसानी से उपयोग कर रहा रूबी में नकल करते जा सकती है instance_eval :

def with(object, &block)
  object.instance_eval &block
end

with विधि मूल वस्तुओं पर तरीकों पर अमल करने के लिए इस्तेमाल किया जा सकता है:

hash = Hash.new

with hash do
  store :key, :value
  has_key? :key       # => true
  values              # => [:value]
end

तरीकों को गतिशील रूप से परिभाषित करना

रूबी के साथ आप निष्पादन समय में कार्यक्रम की संरचना को संशोधित कर सकते हैं। इसे करने का एक तरीका है, विधि method_missing का उपयोग करके विधियों को परिभाषित करना।

मान लीजिए कि हम यह जांचना चाहते हैं कि कोई संख्या वाक्यविन्यास 777.is_greater_than_123? साथ अन्य संख्या से अधिक है 777.is_greater_than_123?

# open Numeric class
class Numeric
  # override `method_missing`
  def method_missing(method_name,*args)
    # test if the method_name matches the syntax we want
    if method_name.to_s.match /^is_greater_than_(\d+)\?$/
      # capture the number in the method_name
      the_other_number = $1.to_i
      # return whether the number is greater than the other number or not
      self > the_other_number
    else
      # if the method_name doesn't match what we want, let the previous definition of `method_missing` handle it
      super
    end
  end
end

एक महत्वपूर्ण बात यह याद रखें कि method_missing का उपयोग करते समय किसी को respond_to? ओवरराइड करना चाहिए respond_to? तरीका:

class Numeric
   def respond_to?(method_name, include_all = false) 
     method_name.to_s.match(/^is_greater_than_(\d+)\?$/) || super
   end
end

ऐसा करने के लिए भूल जाने से असंगत स्थिति पैदा होती है, जब आप सफलतापूर्वक 600.is_greater_than_123 कॉल कर सकते हैं, लेकिन 600.respond_to(:is_greater_than_123) गलत है।

उदाहरणों पर तरीकों को परिभाषित करना

माणिक में आप किसी भी वर्ग के मौजूदा उदाहरणों में विधियाँ जोड़ सकते हैं। यह आपको उस वर्ग के बाकी उदाहरणों के व्यवहार को बदलने के बिना किसी वर्ग के व्यवहार और उदाहरण को जोड़ने की अनुमति देता है।

class Example
  def method1(foo)
    puts foo
  end
end

#defines method2 on object exp
exp = Example.new
exp.define_method(:method2) {puts "Method2"}

#with method parameters
exp.define_method(:method3) {|name| puts name}

भेजना () विधि

send() का उपयोग object संदेश send() लिए किया जाता है। send() Object क्लास का एक इंस्टेंस तरीका है। send() में पहला तर्क send() संदेश है कि आप वस्तु को भेज रहे हैं - वह है, एक विधि का नाम। यह string या symbol हो सकता है लेकिन प्रतीकों को प्राथमिकता दी जाती है। फिर उन तर्कों को विधि में पारित करने की आवश्यकता है, वे शेष तर्क send()

class Hello
  def hello(*args)
    puts 'Hello ' + args.join(' ')
  end
end
h = Hello.new
h.send :hello, 'gentle', 'readers'   #=> "Hello gentle readers"
# h.send(:hello, 'gentle', 'readers') #=> Here :hello is method and rest are the arguments to method.

यहाँ अधिक वर्णनात्मक उदाहरण है

class Account
  attr_accessor :name, :email, :notes, :address

  def assign_values(values)
    values.each_key do |k, v|
      # How send method would look a like
      # self.name = value[k]
      self.send("#{k}=", values[k])
    end
  end
end

user_info = {
  name: 'Matt',
  email: '[email protected]',
  address: '132 random st.',
  notes: "annoying customer"
}

account = Account.new
If attributes gets increase then we would messup the code
#--------- Bad way --------------
account.name = user_info[:name]
account.address = user_info[:address]
account.email = user_info[:email]
account.notes = user_info[:notes]

# --------- Meta Programing way --------------
account.assign_values(user_info) # With single line we can assign n number of attributes

puts account.inspect

नोट: send() स्वयं अनुशंसित नहीं है। __send__() उपयोग करें जिसमें निजी तरीकों को कॉल करने की शक्ति है, या (अनुशंसित) public_send()



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow