2011-06-10 6 views
25

Я делаю некоторое отражение и сталкивался с неожиданным дорожным блоком.Рубиновый метод, который возвращает себя

Есть метод объекта в Ruby (или рельсы), который возвращает себе

ruby-1.9.2> o = Object.new 
=> #<Object:0x00000104750710> 
ruby-1.9.2> o.class 
=> Object 
ruby-1.9.2> o.send :self 
NoMethodError: undefined method `self' for #<Object:0x00000104750710> 

То, что я хочу

ruby-1.9.2> o.send :self 
=> #<Object:0x00000104750710> 

Является ли это встроенный? Или мне нужно расширить объект (Это всегда заставляет меня нервное открытие до объекта):

class Object 

    def itself 
    self 
    end 

end 

А потом так:

ruby-1.9.2> o.send :itself 
=> #<Object:0x00000104750710> 

Ok, некоторый фон на то, что я пытаюсь достичь , У меня есть универсальный помощник таблицы в моей рельсы приложение, и вы называете, если так:

render_list @person, [{field: :name, link_to: :itself}, 
         {field: {address: :name}, link_to: :address}] 

Я изо всех сил на правильном пути, чтобы позвонить :itself - но я думаю, что мой патч путь ,

+1

Непонятно, что вы пытаетесь сделать здесь. Насколько я знаю, 'self' - это не совсем метод, но ссылка на текущий контекст. Вы ожидаете, что 'o.self' будет отличаться от' o' каким-то образом? – tadman

+0

Возможно, люди могли бы дать более полезный ответ, если бы вы дали пример своей конечной цели? –

+0

@brett - добавлено – Jonathan

ответ

33

Да! Если у вас есть Ruby 2.2.0 или новее, вы можете использовать метод Kernel#itself.

Вы можете увидеть подробное обсуждение этой функции здесь: https://bugs.ruby-lang.org/issues/6373. Патч был представлен Рафаэлем Франсой в сообщении № 53.

Вы можете увидеть это в официальном источнике Ruby, глядя в object.c.

+0

Да, это так здорово! – Jonathan

+0

Кроме того, если вы используете Rails (или просто Active Support), вы должны иметь это даже в старых версиях Ruby. – johncip

4

selfis объект сам по себе, не нужно дополнительно его извлекать. После того, как ваш патч, попробуйте следующее:

>> a=[2,3,4] #=> [2, 3, 4] 
>> a == a.itself #=> true 
>> a.object_id #=> 71056290 
>> a.itself.object_id #=> 71056290 

... это точно то же

+0

Вы можете просто использовать «o» всякий раз, когда будете использовать «o.itself». Другими словами, нет необходимости исправлять рубин. – Bira

+0

На самом деле это имеет смысл - '[1,2,3] .index_by (&: self)', но теперь я более склонен к определению 'lambda {| * x | x} 'глобально –

+0

коррекция: lambda {| x | x} –

3

self это ключевое слово со ссылкой на приемник по умолчанию. Это не метод. См. Пример this page.

Ваш метод itself работает нормально. Можно также сказать:

o.instance_eval('self') 

Для класса используйте class_eval вместо:

Object.class_eval('self') 
+6

'o .instance_eval ('self') 'довольно сумасшедший способ сказать' o'. – tadman

+1

@ tadman - иногда необходимо, т.е. в моем случае я делаю некоторое отражение, где мне нужна эта функциональность – Jonathan

5

Если вы используете Ruby-версии> = 1.9 вы можете использовать tap метод с пустым блоком:

Object.tap{}  => Object 
Object.new.tap{} => #<Object:0x5f41334> 
+0

neat - я никогда не знал об этом методе – Jonathan

+3

К сожалению, требуемый блок означает, что вы не можете просто передать ссылку: коснитесь слепо, вы должны быть уверены всегда вызовите его с помощью блока. –

Смежные вопросы