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 argumentelement
, and you further know that the operation succeeds. Getting back the value ofelement
from the method is not useful. Having a return value ofself
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
How to Overwrite a Printed Line in the Shell with Ruby
How to Create Wizard Forms in Ruby on Rails
Rack::Request - How to Get All Headers
Ruby Timeouts and System Commands
Ruby - Digest::Digest Is Deprecated; Use Digest
Yaml Indentation for Array in Hash
Deleting a Modified Object from a Set in a No-Op
Why Can't I Use an Integer as a Key Using the New Ruby 1.9.2 Hash Syntax
Rspec --Init Not Working/ 'Mkd Ir': Invalid Argument - ./C: (Errno::Einval)
How to Add to a Serialized Array
How to Robustly Parse Malformed CSV
What Does "+=" (Plus Equals) Mean
Use of Caret Symbol (^) in Ruby
Ruby Backslash to Continue String on a New Line