هل من الممكن تحديد روبي المفرد طريقة استخدام كتلة ؟

StackOverflow https://stackoverflow.com/questions/135995

سؤال

لذا أريد تعريف المفرد طريقة كائن ، ولكن أريد أن تفعل ذلك باستخدام الإغلاق.

على سبيل المثال ،

def define_say(obj, msg)
  def obj.say
    puts msg
  end
end

o = Object.new
define_say o, "hello world!"
o.say

هذا لا ينفع لأن تعريف المفرد طريقة عبر "مواطنه" ليست الإغلاق ، حتى أحصل على استثناء "msg" هو متغير غير معروف أو الأسلوب.

ما أود القيام به هو شيء من هذا القبيل باستخدام "define_method" طريقة في وحدة الصف ، ولكن بقدر ما أستطيع أن أقول, هذا لا يمكن إلا أن تستخدم لتحديد طريقة على فئة...ولكن أريد المفرد طريقة...

لذا أود أن أكتب شيئا من هذا القبيل:

def define_say(obj, msg)
  obj.define_singleton_method(:say) {
    puts msg
  }
end

لا أحد يعرف كيف يمكن تحقيق هذا دون الحاجة إلى إنشاء طريقة لتخزين Proc ومن ثم استخدام Proc داخل المفرد الأسلوب ؟ (أساسا, أريد نظيفة غير hacky طريقة للقيام بذلك)

هل كانت مفيدة؟

المحلول

هنا هو الجواب الذي يفعل ما تبحث عنه

def define_say(obj, msg)
  # Get a handle to the singleton class of obj
  metaclass = class << obj; self; end 

  # add the method using define_method instead of def x.say so we can use a closure
  metaclass.send :define_method, :say do
    puts msg
  end
end

الاستخدام (لصق من IRB)

>> s = "my string"
=> "my string"
>> define_say(s, "I am S")
=> #<Proc:0xb6ed55b0@(irb):11>
>> s.say
I am S
=> nil

لمزيد من المعلومات (وقليل من المكتبة مما يجعله أقل فوضوي) قراءة هذا:

http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html

بوصفها جانبا ، إذا كنت روبي مبرمج و أنت لم تقرأ أن تذهب تفعل ذلك الآن~!

نصائح أخرى

Object#define_singleton_method وأضاف أن روبي-1.9.2 بالمناسبة:

def define_say(obj, msg)
  obj.define_singleton_method(:say) do
    puts msg
  end
end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top