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.
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.
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 class methods. Is it getting called on main object?
What is hello being called on?
Whenever there isn't an explicit receiver, the receiver is self
. So the call is implicitly:
self.hello
... where self
is the class Test
, on which you have just defined the self.hello
method.
goodbye
is not found because it is defined on an instance of class Test
, not the class itself, where it's currently called.
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
Methods in Ruby: objects or not?
Methods are a fundamental part of
Ruby's syntax, but they are not values
that Ruby programs can operate on.
That is, Ruby's methods are not
objects in the way that strings,
numbers, and arrays are. It is
possible, however, to obtain a Method
object that represents a given method,
and we can invoke methods indirectly
through Method objects.
From The Ruby Programming Language:
How do I reference a function in Ruby?
Ruby doesn't have functions. It only has methods (which aren't first-class) and Proc
s which are first-class, but are not associated with any object.
So, this is a method:
def foo(bar) puts bar end
foo('Hello')
# Hello
Oh, and, yes, this is a real method, not a top-level function or procedure or something. Methods defined at the top-level end up as private(!) instance methods in the Object
class:
Object.private_instance_methods(false) # => [:foo]
This is a Proc
:
foo = -> bar { puts bar }
foo.('Hello')
# Hello
Notice that Proc
s are called differently from methods:
foo('Hello') # method
foo.('Hello') # Proc
The foo.(bar)
syntax is just syntactic sugar for foo.call(bar)
(which for Proc
s and Method
s is also aliased to foo[bar]
). Implementing a call
method on your object and then calling it with .()
is the closest thing you will get to Python's __call__
ables.
Note that an important distinction between Ruby Proc
s and Python lambdas is that there are no restrictions: in Python, a lambda can only contain a single statement, but Ruby doesn't have the distinction between statements and expressions (everything is an expression), and so this limitation simply doesn't exist, therefore in a lot of cases where you need to pass a named function as an argument in Python because you cannot express the logic in a single statement, you would in Ruby simply pass a Proc
or a block instead, so that the problem of the ugly syntax for referencing methods doesn't even arise.
You can wrap a method in a Method
object (which essentially duck-types Proc
) by calling the Object#method
method on an object (which will give you a Method
whose self
is bound to that particular object):
foo_bound = method(:foo)
foo_bound.('Hello')
# Hello
You can also use one of the methods in the Module#instance_method
family to get an UnboundMethod
from a module (or class, obviously, since a class is-a module), which you can then UnboundMethod#bind
to a particular object and call. (I think Python has the same concepts, albeit with a different implementation: an unbound method simply takes the self argument explicitly, just like the way it is declared.)
foo_unbound = Object.instance_method(:foo) # this is an UnboundMethod
foo_unbound.('Hello')
# NoMethodError: undefined method `call' for #<UnboundMethod: Object#foo>
foo_rebound = foo_unbound.bind(self) # this is a Method
foo_rebound.('Hello')
# Hello
Note that you can only bind an UnboundMethod
to an object which is an instance of the module you took the method from. You cannot use UnboundMethods
to "transplant" behavior between unrelated modules:
bar = module Foo; def bar; puts 'Bye' end; self end.instance_method(:bar)
module Foo; def bar; puts 'Hello' end end
obj = Object.new
bar.bind(obj)
# TypeError: bind argument must be an instance of Foo
obj.extend(Foo)
bar.bind(obj).()
# Bye
obj.bar
# Hello
Note, however, that both the Method
and the UnboundMethod
are wrappers around the method, not the method itself. Methods are not objects in Ruby. (Contrary to what I have written in other answers, BTW. I really need to go back and fix those.) You can wrap them in objects, but they aren't objects, and you can see that because you essentially get all the same problems you always get with wrappers: identity and state. If you call method
multiple times for the same method, you will get a different Method
object every time. If you try to store some state on that Method
object (such as Python-style __doc__
strings, for example), that state will be private to that particular instance, and if you try to retrieve your docstring again via method
, you will find that it is gone.
There is also syntactic sugar in the form of the method reference operator .:
:
bound_method = obj.:foo
Which is identical to
bound_method = obj.method(:foo)
How to get reference to object you're calling in method?
dup
class Array
def new_self
dup
end
def plus_one
arr = dup
arr.map! { |i| i + 1 }
end
def plus_one!
arr = self
arr.map! { |i| i + 1 }
end
end
array = [1, 3, 5]
array.new_self # => [1, 3, 5]
array.plus_one # => [2, 4, 6]
array # => [1, 3, 5]
array.plus_one! # => [2, 4, 6]
array # => [2, 4, 6]
dup
makes a copy of the object, making it a safer choice if you need to manipulate data without mutating the original object. You could use self
i.e. arr = self
, but anything you do that changes arr
will also change the value of self
. It's a good idea to just use dup
.
If you do want to manipulate and change the original object, then you can use self
instead of dup
, but you should make it a "bang" !
method. It is a convention in ruby to put a bang !
at the end of a method name if it mutates the receiving object. This is particularly important if other developers might use your code. Most Ruby developers would be very surprised if a non-bang method mutated the receiving object.
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
.
In Ruby, inside a class method, is self the class or an instance?
That is correct. self
inside a class method is the class itself. (And also inside the class definition, such as the self
in def self.coolpost
.)
You can easily test these tidbits with irb:
class Foo
def self.bar
puts self.inspect
end
end
Foo.bar # => Foo
Related Topics
Why Is Throw and Catch Hardly Ever Used in Ruby
Rails: How to Print a Decimal as a Percent
Error Installing Rubymine, No Sdk Specified, But It Is Listed
How to Shorten a Uuid to a Specific Length
What's the Best Way to Implement Acls to a Rails Application
What Is the Purpose of Redo and Retry Statements in Ruby
How to Group Numbers into Different Buckets in Ruby
Finding Common String in Array of Strings (Ruby)
Multiple Servers in a Single Eventmachine Reactor
How to Delete a Range of Values from an Array
Twitter 3-Legged Authorization in Ruby
Rails 4: How to Upload Files with Ajax
Require': Cannot Load Such File -- Spec_Helper (Loaderror)
Getting Error "Exceeded Available Parameter Key Space"
Unicode Characters in a Ruby Script
Recovering from a Broken Tcp Socket in Ruby When in Gets()
Ruby -V Dyld: Library Not Loaded: /Usr/Local/Lib/Libgmp.10.Dylib