Jonathan
Jonathan

Reputation: 16349

Ruby method that returns itself

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

Answers (7)

capps
capps

Reputation: 1

Try .presence

>> a=[2,3,4]
 => [2, 3, 4] 
>> a == a.presence
 => true 

Upvotes: 0

Rivenfall
Rivenfall

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

David Grayson
David Grayson

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

Alexey
Alexey

Reputation: 4071

There is a discussion about adding such method: http://bugs.ruby-lang.org/issues/6373

Upvotes: 7

BitOfUniverse
BitOfUniverse

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

Jeff Terrell Ph.D.
Jeff Terrell Ph.D.

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

J-_-L
J-_-L

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

Related Questions