Получение самого объекта ruby-функции - PullRequest
6 голосов
/ 19 декабря 2009

В Ruby все должно быть объектом. Но у меня есть большая проблема, чтобы добраться до объекта функции, определенного обычным способом, например

def f
    "foo"
end

В отличие от Python, f - это результат функции, а не сама функция. Следовательно, f(), f, ObjectSpace.f - это все "foo". Также f.methods возвращает только список строковых методов.

Как получить доступ к самому объекту функции?

Ответы [ 7 ]

10 голосов
/ 19 декабря 2009

Вы просто используете метод method. Это вернет экземпляр Method, который соответствует этому методу. Некоторые примеры:

>> def f
>>   "foo"
>> end
=> nil
>> f
=> "foo"
>> method(:f)
=> #<Method: Object#f>
>> method(:f).methods
=> [:==, :eql?, :hash, :clone, :call, :[], ...]
>> class SomeClass
>>   def f
>>     "bar"
>>   end
>> end
=> nil
>> obj = SomeClass.new
=> #<SomeClass:0x00000001ef3b30>
>> obj.method(:f)
=> #<Method: SomeClass#f>
>> obj.method(:f).methods
=> [:==, :eql?, :hash, :clone, :call, :[], ...]

Надеюсь, это поможет.

3 голосов
/ 19 декабря 2009

Метод method даст вам Method объект

f = obj.method :f
puts f.call # or f[]

это f связано с объектом. Вы также можете получить несвязанный метод:

unbound_plus = Fixnum.instance_method('+')
plus_2 = unbound_plus.bind(2)

(есть также способ отмены привязки)

2 голосов
/ 19 декабря 2009

ну, я нашел ответ сам

obj = method :f

спасибо всем за вдохновение :) 1004 *

1 голос
/ 19 декабря 2009

Это не функция; это метод объекта. Если вы хотите получить объект, представляющий метод, вы запрашиваете у объекта-владельца:

someobj.method :f

Например:

plus_one = 1.method :+
plus_one[9] # 10
1 голос
/ 19 декабря 2009

В Ruby то, что вы просите, не имеет смысла. (Это имеет смысл в таких языках, как Python, JavaScript, Java и C #.)

В Ruby вы можете указать классу, на какие сообщения он должен отвечать и каким образом он должен отвечать на эти сообщения. Самый распространенный способ сообщить классу, что нужно определить метод в классе. Но опять же, это просто означает: когда кто-то отправляет сообщение f этому экземпляру, вот поведение, которому должен отвечать экземпляр. Функционального объекта нет.

Вы можете делать такие вещи, как получить символ (method_name = :foo) и получить замыкание (method = proc { obj.foo }).

0 голосов
/ 20 декабря 2009

Вы должны создать Proc объект, если вы хотите функциональный объект

f = Proc.new { |x| x * 2 }

Вы вызываете функцию, используя

f.call(8) # => 16

или

f[8] # => 16

вы даже можете использовать этот функциональный объект в операции map

[1, 2, 3, 4, 5].map(&f) # => [2, 4, 6, 8, 10]
0 голосов
/ 19 декабря 2009

Вы можете получить объект, который будет соответствовать этой функции во время выполнения, но, насколько я знаю, нет эквивалента тому, что Python позволяет вам делать прямо в определении функции / класса.

Надеюсь, кто-то докажет, что я не прав, но мне так и не удалось это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...