Hoping to poll the collective consciousness here since I can't structure this in a way to find an answer via search. In Ruby 1.9+, calling .methods on an instance will yield different results than on the class of that instance. For example, "foo".methods will include 'length' and 'size' whereas String.methods will not. What is the reason for this? I am a veteran programmer but new to Ruby. From my understanding, methods is supposed to include all ancestor methods, so is it through a mixin or some other pattern that length and size are added into the instance's list but not the class's?
You're confusing .methods() with .instance_methods().
The first will give you the methods which can be invoked on the String object - that is the String class as an object itself. The second will give you the methods of objects created using the String class, or instances of String.
Length and size are String instance methods, why would they be included in a list of String's (a class) methods? Classes are objects and have their own methods.
In other words, you get the list of methods supported by the object you're calling it on. String is a class, so you get its specific class methods, plus class methods it inherits.
A string instance is an instance, so you get string's instance methods, and instance methods it inherits.
Related
When sent a message, a Ruby object searches to see whether it has a method by that name to respond with. Its method lookup searches in the following order, and uses the first method it finds.
Singleton methods defined on itself (aka methods on its "eigenclass")
Methods defined in its class
Any modules mixed into its class, in reverse order of inclusion (only the earliest inclusion of a given module has any effect - if the superclass includes module A, and the subclass includes it again, it’s ignored in the subclass; if the subclass includes A then B then A, the second A is ignored) (update: note that this was written before Module.prepend existed)
Its parent class
Any methods mixed into the parent class, the parent's parent, etc.
Or, to put it more simply, it looks on itself, then everything in self.class.ancestors in the order they're listed.
This lookup path is followed at the moment the method is called; if you make an instance of a class, then reopen the class and add a method or mix one in via a module, the existing instance will gain access to that method.
If all of this fails, it looks to see if it has a method_missing method, or if its class does, its parent class, etc.
My question is this: aside from examining the code by hand, or using example methods like puts "I'm on module A!", can you tell where a given method came from? Can you, for example, list an object's methods and see "this one is on the parent class, this one is on module A, this one is on the class and overrides the parent class," etc?
Object#method returns a Method object giving meta-data about a given method. For example:
> [].method(:length).inspect
=> "#<Method: Array#length>"
> [].method(:max).inspect
=> "#<Method: Array(Enumerable)#max>"
In Ruby 1.8.7 and later, you can use Method#owner to determine the class or module that defined the method.
To get a list of all the methods with the name of the class or module where they are defined you could do something like the following:
obj.methods.collect {|m| "#{m} defined by #{obj.method(m).owner}"}
Get the appropriate Method (or UnboundMethod) object and ask for its owner. So you could do method(:puts).owner and get Kernel.
To find which instance methods are defined on A (but not on superclasses):
A.instance_methods(false)
To find which instance methods are defined on A AND its superclasses:
A.instance_methods
To find which class (or module) a given method is defined on:
method(:my_method).owner
To find which object is the receiver for a given method:
method(:my_method).receiver
You can use Object#method. For example,
[1, 2, 3].method(:each_cons) # => #<Method: Array(Enumerable)#each_cons>
tells that the each_cons method of an Array comes from the Enumerable module.
Is method an object in Ruby? My friend asked me this question.I read about this in website.But still I didn't understand it.Can anyone help me?
There seems to be a confusion here due to ambiguity of the term method. Method in the most ordinary sense is not an object. In the following:
"foo".upcase
the method upcase is applied to an object "foo", but upcase is not an object, as can be seen by the fact that it cannot stand alone:
upcase # => error
(Do not confuse this with when it can be considered that the receiver is omitted).
However, there is a class Method, whose instances correspond to methods, and are objects. They may also be called methods, but that is not the normal usage of the term method.
No, they are not.
Methods themselves are a language structure of Ruby, and they are not objects. But there is a class Method, whose instances represent methods, and can be called using Method#call.
Also, there is another kind of instances - instances of class UnboundMethod, which represent methods that are detached from specific objects. They can't be called directly, but can be used in many different ways.
If you are looking for something like Javascript's functions, then procs and lambdas are what you want.
This question already has answers here:
Ruby metaclass confusion
(4 answers)
Closed 7 years ago.
I don't quite get some things about the Ruby object model. First, is EVERYTHING in Ruby an instance of Class? These all produce true:
p Object.instance_of?(Class)
p Class.instance_of?(Class)
p Module.instance_of?(Class)
p BasicObject.instance_of?(Class)
class Hello; end
p Hello.instance_of?(Class)
I can't quite get how is it possible, if Object is a superclass of Class, how can it be both a superclass of Class and an instance of it at the same time (most diagrams on the Ruby Object Model clearly state this hierarchy)? Which allows for some crazyness like this:
p BasicObject.is_a?(Object) #=> true
where BasicObject.class is Class, and Class.is_a?(Object).
By the way, using Ruby 2.0.
First, is EVERYTHING in Ruby an instance of Class?
No, not everything is an instance of Class. Only classes are instances of Class.
There are lots of things which aren't instances of Class: strings, for example, are instances of String, not Class. Arrays are instances of Array, integers are instances of Integer, floats are instances of Float, true is an instance of TrueClass, false is an instance of FalseClass, nil is an instance of NilClass, and so on.
Every class is an instance of Class, just like every string is an instance of String.
if Object is a superclass of Class, how can it be both a superclass of Class and an instance of it at the same time (most diagrams on the Ruby Object Model clearly state this hierarchy)?
Magic.
Just like in most other languages, there are some core entities that are simply assumed to exist. They fall from the sky, materialize out of thin air, magically appear.
In Ruby, some of those magic things are:
Object doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is always Object. [Note: there may be implementation-defined superclasses of Object, but eventually, there will be one which doesn't have a superclass.]
Object is an instance of Class, which is a subclass of Object (which means that indirectly Object is an instance of Object itself)
Class is a subclass of Module, which is an instance of Class
Class is an instance of Class
None of these things can be explained in Ruby.
BasicObject, Object, Module and Class all need to spring into existence at the same time because they have circular dependencies.
Just because this relationship cannot be expressed in Ruby code, doesn't mean the Ruby Language Specification can't say it has to be so. It's up to the implementor to figure out a way to do this. After all, the Ruby implementation has a level of access to the objects that you as a programmer don't have.
For example, the Ruby implementation could first create BasicObject, setting both its superclass pointer and its class pointer to null.
Then, it creates Object, setting its superclass pointer to BasicObject and its class pointer to null.
Next, it creates Module, setting its superclass pointer to Object and its class pointer to null.
Lastly, it creates Class, setting its superclass pointer to Module and its class pointer to null.
Now, we can overwrite BasicObject's, Object's, Module's, and Class's class pointer to point to Class, and we're done.
This is easy to do from outside the system, it just looks weird from the inside.
You should notice that:
p BasicObject.instance_of?(BasicObject)
prints false.
That is, the expression BasicObject is not an instance of BasicObject, it is an instance of something else, that is, it is a Class object, which represents an object that holds (for example) the class methods, such as new.
For example:
p (BasicObject.new()).instance_of?(BasicObject)
prints true, and
p (BasicObject.new()).instance_of?(Class)
prints false.
All of your examples were by definition classes. Classes are also objects. But what you didn't do was look at an instance of a class:
p Object.new.class
p Hello.new.class
Classes define the form of an object, and by definition, a class is a Class. But when you instantiate class into an object, the object is the new type. But you can still see that the object's class is itself Class:
p Hello.new.class.class
I am wondering if there is a Ruby method call that shows only the methods defined by the Ruby object it's called from, as opposed to all the methods defined by its ancestor classes, which is what methods seems to do.
methods takes an optional boolean parameter, which specifies whether to also list the methods from the object's class and its superclasses or just the object's singleton methods. So you can do obj.methods(false) to only get the singleton methods defined on obj.
If you want the methods defined by the object's class, but not those defined by its superclasses, you can get that by calling instance_methods(false) on the object's class, so it's obj.class.instance_methods(false).
I'm partial to obj.methods.sort but some of the other answers are better in certain cases as they describe
You can also use obj.methods.sort.grep /foo/ to find method names matching the regexp.
This is helpful when you have an idea of what you're looking for.
You have a few options - object.methods, object.public_methods, object.singleton_methods... it depends on what you want. Since they both return an array, you might want to try something like:
# obj is the current object
parent = obj.class.superclass
methods = (obj.methods - parent.methods)
we can call the Array method in the top level like this
Array(something)
that makes sense to me, it's a method call without explicit receiver, and self, which is main in this case, is inserted at the front of the method call. But isn't it that this is equivalent to :
Kernel.Array(something)
this doesn't make sense to me. Since in the first case, the object main is of class Object, which got Kernel module mixed in, thus have the Array method. But in the second case, we are calling the Array method on the Kernel module object itself, rather than main object, didn't they are NOT the same thing?
sorry for my bad english.
Kernel.Array is what is known as a module function. Other examples of module functions include Math.sin, and Math.hypot and so on.
A module function is a method that is both a class method on the module and also a private instance method. When you invoke Array() at the top-level you are invoking it as a private instance method of the main object. When you invoke it through Kernel.Array() you are invoking it as a class method on Kernel. They are the same method.
To learn more, read up on the module_function method in rubydocs: http://www.ruby-doc.org/core/classes/Module.html#M001642
class Object mixed-in module Kernel, but Kernel is an instance of Object. So Kernel "module" methods - is it's instance methods.
What's confusing you is the difference between class and instance methods.
Class methods don't have an explicit receiver, and thus no self to access other fields with. They just... are.
Generally instance methods are used to query or manipulate the attributes of a given object, whereas the class methods are "helper" or "factory" methods that provide some functionality associated with or especially useful for a certain kind of class, but not dependent on actual live instances (objects) of that class.
Not sure about Ruby, but Java has (for example) a whole class, Math that contains nothing but instance methods like sin(), max(), exp() and so forth: There is no "Math" object, these are just methods that embody mathematical algorithms. Not the best example, because in Ruby those methods are probably embedded right into the numeric classes as instance methods.
The case you mention is a bit confusing because Array's () method and Kernel's Array() method are in fact different methods that do similar things. Both are class methods.
Array() takes a list of arguments and makes and returns an array containing them.
Kernel.Array() takes a single argument of an "array-able" type, such as a sequence, and takes the values returned by this argument and builds an array from those.
UPDATE
The downvote was perhaps justified; I apologize for taking on a subject outside my area of expertise. I think I'll be deleting this answer soon.
# Chuck: I would sincerely hope that a language/library's official documentation would offer some meaningful clues as to how it works. This is what I consulted in answering this question.
The rdoc for Kernel.Array():
Returns arg as an Array. First tries to call arg.to_ary, then arg.to_a. If both fail, creates a single element array containing arg (unless arg is nil).
for Array.():
Returns a new array populated with the given objects.
I don't know about you, but I think if the docs vary that much then either they're talking about separate methods or the documentation is a train wreck.
# freeknight:
But everything in ruby is an object of some kind, even classes and modules. And Kernel.Array is actually a method call on an specific object - the Kernel object.
Yeah, under the covers it's similar in Java too. But the Array() method isn't doing anything with Kernel, any more than Array() is doing anything with the Array class object, so this is really only a semantic quibble. It's an instance method because you could hang it off class IPSocket if you were crazy enough, and it would still work the same way.
They are the same thing:
a = Kernel.Array('aa')
=> ["aa"]
a.class
=> Array
a = Array('aaa')
=> ["aaa"]
a.class
=> Array
Maybe there is an alias?