Reputation: 16349
I am doing some reflection, and ran into an unexpected road block.
Is there an object method in ruby (or rails) that returns itself
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>
What I want
ruby-1.9.2> o.send :self
=> #<Object:0x00000104750710>
Is this built in? Or do I need to extend Object (It always gets me nervous opening up Object):
class Object
def itself
self
end
end
And then so:
ruby-1.9.2> o.send :itself
=> #<Object:0x00000104750710>
Ok, some background on what I am trying to achieve. I have a generic table helper in my rails app, and you call if like so:
render_list @person, [{field: :name, link_to: :itself},
{field: {address: :name}, link_to: :address}]
I was struggling on the right way to call :itself
-- but i'm thinking that my patch is the way to go.
Upvotes: 34
Views: 15734
Reputation: 1263
There is a #yourself method in Smalltalk. It has sense because of the syntax of the language where you can send several messages to the same object and want to get the object itself at the end of the phrase.
aList add: (anObjet doThis; andThat; yourself).
Also in Smalltalk the default return value for a method is self, but in Ruby it's the last instruction's return value (or nil if there is nothing in the method). Anyway maybe we should all start using explicit returns :)
If for some weird logic reason you have to call a method on some object but what you want is really the object itself, then I don't see why you couldn't extend the Object class to do just that.
There's really no reason why it would break your program unless the method exists somewhere else (did or will exist) and did (or will) do something else. Maybe a slight loss in performance?
Upvotes: 0
Reputation: 87416
Yes! If you have Ruby 2.2.0 or later, you can use the Kernel#itself
method.
You can see the extensive discussion of this feature here: https://bugs.ruby-lang.org/issues/6373. The patch was submitted by Rafael França in message #53.
You can see it in the official Ruby source by looking in object.c.
Upvotes: 51
Reputation: 4071
There is a discussion about adding such method: http://bugs.ruby-lang.org/issues/6373
Upvotes: 7
Reputation: 6021
If you are using Ruby version >= 1.9 you can use tap
method with empty block:
Object.tap{} => Object
Object.new.tap{} => #<Object:0x5f41334>
Upvotes: 6
Reputation: 2711
self
is a keyword referring to the default receiver. It is not a method. See this page for an example.
Your itself
method works fine. You can also say:
o.instance_eval('self')
For a class, use class_eval
instead:
Object.class_eval('self')
Upvotes: 3
Reputation: 9177
self
is the object itself, no need to extra fetch it. After your patch, try the following:
>> a=[2,3,4] #=> [2, 3, 4]
>> a == a.itself #=> true
>> a.object_id #=> 71056290
>> a.itself.object_id #=> 71056290
...it is exactly the same
Upvotes: 4