Можно ли определить одноэлементный метод Ruby с помощью блока?

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

Это не работает, поскольку определение одноэлементного метода с помощью «def» не является замыканием, поэтому я получаю исключение, что «msg» является неопределенной переменной или методом.

Я хотел бы сделать что-то вроде использования метода «define_method» в классе модуля, но, насколько я могу судить, это можно использовать только для определения метода в классе...но мне нужен метод Singleton...

Итак, я хотел бы написать это примерно так:

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

Кто-нибудь знает, как я могу добиться этого без необходимости создавать метод для хранения Proc, а затем использовать Proc в одноэлементном методе?(по сути, мне нужен чистый, нехакерский способ сделать это)

Это было полезно?

Решение

Вот ответ, который делает то, что вы ищете

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

Кстати, если вы программист на Ruby и НЕ читали это, сделайте это прямо сейчас~!

Другие советы

Object#define_singleton_method кстати, было добавлено в Ruby-1.9.2:

def define_say(obj, msg)
  obj.define_singleton_method(:say) do
    puts msg
  end
end
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top