Ruby Method That Returns Itself

Ruby method that returns itself

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.

Why is self being returned in Ruby

It is due to difference in use case.

  • When you use push, you use it with the argument element, and you further know that the operation succeeds. Getting back the value of element from the method is not useful. Having a return value of self makes it more convenient such as allowing chaining of the methods.
  • When you use pop, in useful cases, you are not sure whether the array has an element in it (otherwise it falis), and what element you get by popping. And getting back the popped value is the purpose of using the method.

In other words, push is a "setter/modifyer" method whereas pop is a (destructive) "getter" method.

Getting ruby function object itself

You simply use the method method. This will return the Method instance that matches with that method. Some examples:

>> 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, :[], ...]

Hope this helps.

Return containing object instance in ruby

First of all, it doesn't matter what class of object is contained within a Query instance. All of the syntax shown on your 'example usage' section is appropriately defined in Query. The only requirement of the objects contained within a query instance is that they respond to as (or some similar method). What you have here is something like a state machine, but the only state that really matters is that some object occupies the last position in the select_statements array. Here's how I would build this (again, based mostly on your example at the end, I'm afraid I can't quite follow your initial explanation):

class Query
# ... initialize, etc.

def select(statement, statement_class = AliasableString)
select_statements << statement_class.new(statement)
self
end

def as(aka)
# this will only ever be used on the most recent statement added
statement_to_alias = select_statements.last

# throw an error if select_statements is empty (i.e., :last returns nil)
raise 'You must add a statement first' unless statement_to_alias

# forward the message on to the statement
statement_to_alias.as(aka)

# return the query object again to permit further chaining
self
end
end

AliasableString doesn't need to know a thing about Query; all it needs to do is respond appropriately to as.

Is there a method in Ruby Object to pass itself to a block or proc?

yield_self has been added to ruby core a month ago as of June 2017. https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/58528

It's in ruby 2.5.0 after revision number 58528, although I'm not exactly sure how to get that code yet. Perhaps if someone knows how they can edit this answer

Ruby method like `self` that refers to instance

self always refers to an instance, but a class is itself an instance of Class. In certain contexts self will refer to such an instance.

class Hello
# We are inside the body of the class, so `self`
# refers to the current instance of `Class`
p self

def foo
# We are inside an instance method, so `self`
# refers to the current instance of `Hello`
return self
end

# This defines a class method, since `self` refers to `Hello`
def self.bar
return self
end
end

h = Hello.new
p h.foo
p Hello.bar

Output:

Hello
#<Hello:0x7ffa68338190>
Hello

Ruby: define a class that returns something other than itself when an instance is called without any methods

If I understand correctly, you want to return the instance of Example when you call the ExamplePresenter instance. Such a direct mechanism does not exist in any language, and even if it did, it would block all access to the ExamplePresenter instance and its methods. So it is not logical.

There is something you can do however. You can make the ExamplePresenter class delegate methods to the Example instance inside it. Effectively you do not get a real Example from @presenter but you get an ExamplePresenter that passes all eligible methods into its internal Example effectively acting in behalf of it.

Some ways of doing this is:

method_missing

class ExamplePresenter
… # as defined in the question

def method_missing symbol, *args
if @example.respond_to?(symbol)
@example.send(symbol, *args)
else
super
end
end
end

This will pass any method call down to the internal Example if the ExamplePresenter cannot respond to it. Be careful, you may expose more than you want of the internal Example this way, and any method already defined on ExamplePresenter cannot be passed along.

You can use additional logic inside method_missing to limit exposure or pre/post process the arguments/return values.

Wrapper methods

You can define wrapper methods on ExamplePresenter that do nothing but pass everything to the internal Example. This gives you explicit control on how much of it you want to expose.

class ExamplePresenter
… # as before

def a_method
@example.a_method
end
def another_method(argument, another_argument)
@example.another_method(argument, another_argument)
end
end

This gets tedious fast, but you can also add logic to alter arguments before passing it along to the Example or post process the results.

You can also mix and match the above two methods

Delegator library

There is a library in Ruby stdlib called Delegator built exactly for this purpose. You may look into it.

What does the Ruby Method#owner return?

I think this will do what you say

class Parent
end

class Child < Parent
end

def Parent.my_method
if singleton_class == method(__method__).owner
puts "called in Parent"
end
end

Parent.my_method
Child.my_method

my_method is defined in the singleton class of class Parent.

When called with Parent, it just works.
If called with Child, it will be looked up through the Child's singleton class and up to the Parent's singleton class.

Because Parent's singleton class is the super class of Child's singleton class.

Ruby - How can I get a method name within itself?

Here is the code:

For versions >= 1.9:

def funky_method

return __callee__

end

For versions < 1.9:

def funky_method

return __method__

end


Related Topics



Leave a reply



Submit