Currently working on a ruby minifier using Ripper's lex() method. However currently attr_accessor is defined as an identifier... I assume because it's a method.
Where is attr_accessor defined? If I know where it's defined I can easily make exceptions for methods like it.
It is defined in the Module class. (Documentation Link)
EDIT:
Just to make the answer more complete, it is a private method of the Module class, which means you cannot call it with a receiver, need to have the class opened to use it (or using some hack like send or eval):
class MyClassOrModule
attr_accessor :foobar
end
You cannot invoke it as MyClassOrModule.attr_accessor. As you already discovered in our comments below, Module.private_instance_methods will show its presence.
Yes, attr_accessor is defined in the class Module (Module#attr_accessor), but how does one go about finding it in the first place? Having to ask someone, or perhaps Googling, is not a very efficient way of going about it.
We can make use of the method Method#owner.1
owner responds to method objects (instances of the class Method), not to method names, which are symbols. Why? Because many modules/classes have methods that have the same symbolic name. For example, String, Array and Hash all have an instance method named :[]. Therefore, we cannot ask Ruby where :[] is defined. We can ask, however, where the method
m = [1,2,3].method(:[])
#=> #<Method: Array#[]
is defined, namely,
m.owner
#=> Array
The determination of m makes use of the method Object#method.
Alternatively, we could write
m = Array.instance_method(:[])
#=> #<UnboundMethod: Array#[]>
m.owner
#=> Array
This makes use of the method Module#instance_mathod.
Notice that in the first case the method :[] is bound to the instance of Array [1,2,3], whereas in the second case :[] is not bound to any particular instance of Array, so it is referred to as UnboundMethod. Either way, we see that Array#[] is defined in Array (i.e., it is not inherited from an ancestor).
Let's consider another example.
We know that 3.zero? #=> false, but do not find an instance method :zero? in the class Integer. So, where is it? We can write:
m = 3.method(:zero?)
#=> #<Method: Integer(Numeric)#zero?>
or
m = Integer.instance_method(:zero?)
#=> #<UnboundMethod: Integer(Numeric)#zero?>
then
m.owner
#=> Numeric
Aha! It's defined in Numeric, the superclass of Integer, Float, Rationale and Complex.
Notice that, in computing m, the message displayed includes, "Integer(Numeric)". Even before computing m.owner this tells us that the owner is Numeric. By contrast, in finding the owner of Array#[] the message was simply "Array". Helpful as always, Ruby parenthetically gives the owner when the owner is not the class of the receiver of method or the class that is the receiver of instance_method.
So now let us find the owner of the class method :attr_accessor. We know that this method is available for every class (e.g., Class.new.methods.include?(:attr_accessor) #=> true), so we could write, say,
m = Class.method(:attr_accessor)
#=> #<Method: Class.attr_accessor>
m.owner
#=> Module
since Class is itself a class, but we could have instead written, say,
m = Regexp.method(:attr_accessor)
#=> #<Method: Regexp.attr_accessor>
m.owner
#=> Module
or even
m = Class.instance_method(:attr_accessor)
#=> #<UnboundMethod: Class(Module)#attr_accessor>
m.owner
#=> Module
the last because methods of every class (which is an instance of Class) are instance methods of Class.
1 If one forgets where the instance method owner is defined, just remember that it is defined on methods, which are instances of the class Method.
Related
Ruby's Class class lists two methods named 'new':
Class::new is a public class method
Class#new is a public instance method
But when I do:
Class.methods(false)
#=> []
which is supposed to list singleton methods (which I am assuming what class methods are), I get an empty array. Why is this so? Where is Class::new defined?
The methods shown as ::new in the documentation are usually #initialize, for example Range::new:
new(begin, end, exclude_end=false) → rng
Constructs a range using the given begin and end. If the exclude_end parameter is omitted or is false, the rng will include the end object; otherwise, it will be excluded.
This is because you create instances via:
r = Range.new(0, 2) #=> 0..2
Rather than:
r = Range.allocate #=> nil..nil
r.send(:initialize, 0, 2) #=> nil
r #=> 0..2
That's exactly what ::new does – it creates a new instance via allocate, sends it initialize (passing arguments) and returns the instance.
The actual new method is inherited from Class (since Range is an instance of Class) – Class#new:
new(args, ...) → obj
Calls allocate to create a new object of class’s class, then invokes that object’s initialize method, passing it args. This is the method that ends up getting called whenever an object is constructed using .new.
Just like allocate, inherited and superclass (and the instance methods from Class' ancestors like Module as well):
Range.method(:new)
#=> #<Method: Class#new>
Range.method(:allocate)
#=> #<Method: Class#allocate>
Range.method(:ancestors)
#=> #<Method: Class(Module)#ancestors>
So if you call Class.new:
my_string_class = Class.new(String)
#=> #<Class:0x007fdf5485b200>
you just invoke Class#new which is (again) equivalent to:
my_string_class = Class.allocate
my_string_class.send(:initialize, String)
my_string_class
#=> #<Class:0x007fdf5484beb8>
One notable exception is Struct which in fact provide its own new class method:
Struct.method(:new)
#=> #<Method: Struct.new>
Unlike other classes, Struct::new does not return instances of Struct but instances of Class (which are subclasses of Struct).
tl;dr summary:
Why is this so?
Because it's not a singleton method.
Where is Class::new defined?
It isn't. The call Class.new is just calling Class#new (since Class is an instance of itself). The documentation for Foo::new is actually the documentation for Foo#initialize for any class Foo, including Class itself.
If you want to know something about Ruby, it is often a good idea to ask her herself:
new_method = Class.method(:new)
#=> #<Method: Class#new (defined in Class at core/alpha.rb:90)>
The Object#method method returns a Method object representing the method. (Methods aren't objects in Ruby themselves, but you can get a reflective proxy object that represents a method.)
You can ask a Method where it is defined using the Method#owner method:
new_method.owner
#=> Class
As you can see, new is defined in Class and not in Class's singleton class.
You can also ask a Method about the location of its Ruby source code using the Method#source_location method:
new_method.source_location
#=> ['core/alpha.rb', 90]
What this tells us is that Class#new is defined in the file core/alpha.rb on line 90:
def new(*args)
obj = allocate()
Rubinius.asm(args, obj) do |args, obj|
run obj
run args
push_block
send_with_splat :initialize, 0, true
# no pop here, as .asm blocks imply a pop as they're not
# allowed to leak a stack value
end
obj
end
The method is partially implemented in bytecode for performance reasons, but it is basically just:
class Class
def new(*args, &block)
obj = allocate
obj.__send__(:initialize, *args, &block) # because initialize is private
#obj.initialize(*args, &block)
obj
end
end
Now, you might ask yourself: why is there an entry for Class::new in the RDoc documentation, if that method doesn't exist? Well, RDoc knows about the relationship between #initialize which is the method you define but usually don't call directly and Class#new which is the method you call but usually don't define, and it will document #initialize as ::new if it exists.
So, what we really want to look at, is Class#initialize:
initialize_method = Class.method(:initialize)
#=> #<Method: Class#initialize (defined in Class at core/class.rb:15)>
initialize_method.owner
#=> Class
initialize_method.source_location
#=> ['core/class.rb', 15]
This is the source:
def initialize(sclass=Object, name=nil, under=nil)
raise TypeError, "already initialized class" if #instance_type
raise TypeError, "can't make subclass of Class" if Class.equal?(sclass)
set_superclass sclass
# Things (rails) depend on the fact that a normal class is in the constant
# table and have a name BEFORE inherited is run.
under.const_set name, self if under
if sclass
Rubinius.privately do
sclass.inherited self
end
end
super()
end
private :initialize
Class#initialize essentially does three things:
set the superclass
optionally assign the class to a constant to give it a name
call the Class#inherited hook method of the superclass
If you want to know what the relationships between some of the core classes that magically spring into existence at the beginning are, you can take a look at the initialization code of some Ruby execution engines, e.g.
Rubinius: VM::bootstrap_class in machine/ontology.cpp
JRuby: org.jruby.Ruby.initRoot in core/src/main/java/org/jruby/Ruby.java
IronRuby: the initial classes are generated by a program, the generator is in the directory Src/ClassInitGenerator
MRuby: mrb_init_class in src/class.c
Note: depending on what Ruby implementation you use, obviously the places where those methods are defined and how exactly they are defined may vary.
new is defined as a instance method of Class class, rather than a singleton method:
Class.instance_method :new # => #<UnboundMethod: Class#new>
Tricky to note: Class (object) itself is also an instance of Class (class).
Class.instance_of? Class # => true
The number 1 contains 109 additional methods above and beyond the Fixnum class it inherits from.
1.methods - Fixnum.methods => [:%, :&, :*, :**, :+, :+#, :-, :-#, ...]
(1.methods - Fixnum.methods).count => 109
1.is_a? Fixnum => true
So from my understanding, I would say the number 1 is an instance of Fixnum. But why does the number 1 have so many more methods than Fixnum? And where do they come from? How would I write my own method for the number 1?
When you call .methods, it gives the methods defined on that instance. So when you ask for Fixnum.methods, you get the methods you can call on Fixnum the class, not on objects of type Fixnum.
As to your last question, Ruby allows you to extend a class like so:
class Fixnum
def plus9
return self + 9
end
end
They can come from Fixnum's parent classes as well as any modules mixed in along the way. You can use 1.method('<method name>').inspect to find out where exactly does the method originate.
method#source_location is good as well, but it doesn't work for native methods, which is almost everything on 1.
Fixnum itself is an instance of Class, when you call Fixnum.methods, it returns the methods that the Class class and its ancestors have.
So 1.methods - Fixnum.methods has little sense as you are comparing the methods of Fixnum class and the methods of Class class.
Fixnum.class
# => Class
1.class
# => Fixnum
How would I write my own method for the number 1
You can implement your own methods in Fixnum or any of its ancestor classes: Integer, Numeric, etc, depending on which class this method makes sense.
You may misunderstand the Object#methods method.
According to the Ruby API,
methods(regular=true) → Returns a list of the names of public and protected methods of obj.
So Fixnum.methods returns the methods from the perspective of the object, not the class.
Module#instance_methods is what you want
1.methods.count == Fixnum.instance_methods.count # => true
To get the right method list in Ruby is kind of a confusing thing, Idiosyncratic Ruby has a detailed post about method-lists. It helps me sort things up, and hope this can help you, too.
To extend the Fixnum class and add/modify your own methods. You can use this code:
class Fixnum
def newNum_method
puts self.methods
end
end
Also you can modify existing methods the same way. Many times the 'to_s' is modified to produce specific results for example:
class Array
def to_s
puts self.join(":")
end
end
This code ONLY modifies what you specify.
You can also add class specific code for example:
def Array.newMethod
puts Array.methods
end
This allows you to call:
puts Array.newMethod
(Which would technically be the same as "puts Array.methods")
but you can customize this to say or do whatever with the 'Array' class
You could even create a method for the Fixnum class itself to Iterate over its parents and list EACH method from them.
def Fixnum.listParentMethods
.....
end
Try
1.methods - Fixnum.instance_methods
and you'll get an empty array.
In ruby, classes are objects of type Class.
When you call obj.methods, it returns all public methods of obj.
So what if obj is a class?
As the title suggests, I would like to assign all the instance methods defined on one class to another. I know at I can get a list of the methods that I want to copy from ClassA to ClassB like this:
ClassA.instance_methods(false)
And I think I can define them on ClassB like this:
ClassA.instance_methods(false).each do |method_name|
ClassB.method_define(method_name, [body here??])
end
Is there a way to get the corresponding method body, and if so, will this method work? If not, is there even a way to do this?
Others already told you to subclass. But to answer your literal question, we would be getting involved with UnboundMethod objects:
class Object
def kokot; 'kokot' end
end
o = Object.new
o.kokot
#=> kokot
3.kokot
#=> kokot
So far so good. Now let's redefine kokot method on Numeric:
class Numeric
def kokot; 'pica' end
end
o.kokot
#=> kokot
3.kokot
#=> pica
But what if we decide, that new kokot method is great for numerics, but just complex numbers should keep using the old kokot method. We can do it like this:
um = Object.instance_method :kokot
#=> #<UnboundMethod: Object#kokot>
Complex( 2, 3 ).kokot # gives the redefined kokot method
#=> pica
Complex.module_exec { define_method :kokot, um }
# Now we've just bound the old kokot to Complex
Complex( 2, 3 ).kokot
#=> kokot
In short, there is a way to "copy and paste" methods among related classes. It is required that the target be a subclass of the unbound method source. Method #source_location shows the file and the line where #kokot has been defined:
um.source_location
#=> ["(irb)", 2]
For built-in methods, #source_location returns nil. In Ruby 2.0, RubyVM class has method #disassemble:
RubyVM::InstructionSequence.disassemble( um )
#=> ( program listing goes here )
In any case, Ruby bytecode is not that beautiful to look at. Going back to your original needs, not even #define_method or UnboundMethod#bind can bind methods to incompatible objects. This cannot be cheated by tricks like redefining #kind_of?, one would have to cheat CLASS_OF() function in the native code...
From the available gems, Sourcify, RubyParser and Sorcerer are of interest. (Thanks, #Casper.) Using these, one could theoretically transplant code between incompatible objects via #eval-ling extracted method source. Long way as it goes, this technique would still fall short of realiable method transfer, as it fails whenever the source is not available at runtime (eg. self-modifying source).
It seems like what you might want is mix-ins:
Taken from http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html
module Debug
def whoAmI?
"#{self.type.name} (\##{self.id}): #{self.to_s}"
end
end
class Phonograph
include Debug
# ...
end
class EightTrack
include Debug
# ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? » "Phonograph (#537766170): West End Blues"
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow"
In ruby 2.0 you can use modules. Matz explicitly forbade this behavior from classes.
But you can use instance_methods from modules.
ModuleA.instance_methods(false).each do |name|
meth = ModuleA.instance_method(name)
ClassB.send(:define_method, name, meth)
end
define_method is a private method, so that's why you use send here.
But why do this? Just include the module.
If you want to just apply behavior to an object you can unbind a method from any module and bind it to any object.
ModuleA.instance_method(:something).bind(some_object).call(args)
If this is what you want, take a look at casting, a gem that adds a convenience to doing delegation like this as well as adding methods to an object only for the life of a block.
In that case, classB should inherit classA.
I am reading the Module documentation but can't seem to understand their differences and which should be used where.
How is the eval different than exec?
I'm going to answer a bit more than your question by including instance_{eval|exec} in your question.
All variations of {instance|module|class}_{eval|exec} change the current context, i.e. the value for self:
class Array
p self # prints "Array"
43.instance_eval{ p self } # prints "43"
end
Now for the differences. The eval versions accepts a string or a block, while the exec versions only accept a block but allow you to pass parameters to it:
def example(&block)
42.instance_exec("Hello", &block)
end
example{|mess| p mess, self } # Prints "Hello" then "42"
The eval version does not allow to pass parameters. It provides self as the first parameter, although I can't think of a use for this.
Finally, module_{eval|exec} is the same as the corresponding class_{eval|exec}, but they are slightly different from instance_{eval|exec} as they change what is the current opened class (i.e. what will be affected by def) in different ways:
String.instance_eval{ def foo; end }
Integer.class_eval { def bar; end }
String.method_defined?(:foo) # => false
String.singleton_methods.include?(:foo) # => true
Integer.method_defined?(:bar) # => true
So obj.instance_{eval|exec} opens the singleton class of obj, while mod.{class|module}_{eval|exec} opens mod itself.
Of course, instance_{eval|exec} are available on any Ruby object (including modules), while {class|module}_* are only available on Module (and thus Classes)
To answer your last question first, eval (in all its variations) is completely different from exec. exec $command will start a new process to run the command you specify and then exit when that finishes.
class_eval and module_eval have the power to redefine classes and modules -- even those that you yourself did not write. For example, you might use class eval to add a new method that did not exist.
Fixnum.class_eval { def number; self; end }
7.number # returns '7'
class_eval can be used to add instance methods, and instance_eval can be used to add class methods (yes, that part is very confusing). A class method would be something like Thing.foo -- you're literally calling the foo method on the Thing class. An instance method is like the example above, using class_eval I've added a number method to every instance of Fixnum.
Okay, so that's the *_eval class of methods. The exec methods are similar, but they allow you to look inside a class and execute a block of code as though it was defined as a method on that class. Perhaps you have a class that looks like this:
class Foo
##secret = 'secret key'
##protected = 'some secret value'
def protected(key)
if key == ##secret
return ##protected
end
end
end
The class Foo is just a wrapper around some secret value, if you know the correct key. However, you could trick the class into giving you its secrets by executing a block inside the context of the class like so:
Foo.class_exec { ##secret = 'i'm a hacker' }
Foo.protected('i'm a hacker') #returns the value of ##protected because we overwrote ##secret
In general, with a lot of the tools in ruby, you could use any of these to solve a lot of problems. A lot of the time you probably won't even need to unless you want to monkey patch a class some library you use has defined (although that opens up a whole can of worms). Try playing around with them in irb and see which you find easier. I personally don't use the *_exec methods as much as the *_eval methods, but that's a personal preference of mine.
To avoid ambiguity I'm going to call a method that belongs to (owned by) a singleton class a singleton method. The rest are instance methods. Although one might say that a singleton method of an object is an instance method of its singleton class.
tl;dr Use class_eval/module_eval on a class/module to define instance methods, and instance_eval on a class/module to define class methods (or to be more precise, use instance_eval to define singleton methods). Additionally you can use instance_eval to access instance variables.
A terminology is a bit lacking in this case. ruby maintains a stack of class references (cref for short). When you open/reopen a class, the corresponding class reference is pushed to the stack. And the current class refernece affects where def defines methods (to which class/module they're added).
Now, class_eval/module_eval and class_exec/module_exec are aliases.
The *_exec() variants don't accept strings, and allow to pass arguments to the block. Since the *_eval() variants are mainly used I'll focus on them.
class_eval/module_eval changes cref and self to the receiver (Thing in Thing.module_eval(...)):
rb_mod_module_eval() -> specific_eval()
yield_under() (for blocks)
vm_cref_push()
eval_under() (for strings)
vm_cref_push()
instance_eval changes cref to the singleton class of the receiver, and self to the receiver.
Let's see them in action:
class A
p self #=> A
#a = 1
def initialize
#b = 2
end
end
p A.instance_variables #=> [:#a]
p A.new.instance_variables #=> [:#b]
#a on a class level adds an instance variable to the class A as an object. I'm adding it here for completeness. But that's not how you add a class variable.
A.instance_eval do
p self #=> A
p #a #=> 1
def m() puts 'm' end
end
sclass = A.singleton_class
p sclass.instance_methods(false).include? :m #=> true
A.m #=> m
a = A.new
a.instance_eval do
p self #=> #<A:0x00007fc497661be8 #b=2>
p #b #=> 2
def m2() puts 'm2' end
end
sclass = a.singleton_class
p sclass.instance_methods(false).include? :m2 #=> true
a.m2 #=> m2
So, inside instance_eval def adds a singleton method to the receiver (an instance method to the singleton class of the receiver). For a class/module that means a class/module method. For other objects, a method that is available for that particular object.
A.class_eval do
p self #=> A
p #a #=> 1
def m() puts 'm' end
end
p A.instance_methods(false).include? :m #=> true
A.new.m #=> m
And, inside class_eval def adds an instance method to the receiver itself (the class/module). class_eval is only available for classes/modules.
Also, when class_eval is passed a block, constant/class variable lookup is not affected:
module A
C = 1
##c = 1
class B
C = 2
##c = 2
end
A::B.class_eval { p [C, ##c] } #=> [1, 1]
A::B.class_eval 'p [C, ##c]' #=> [2, 2]
end
The naming is confusing. I might guess that instance in instance_eval suggests that receiver is treated as an instance (allows to change things for a particular instance), and class in class_eval as a class (allows to change things for a class of objects).
How is it that Ruby allows a class access methods outside of the class implicitly?
Example:
class Candy
def land
homer
end
end
def homer
puts "Hello"
end
Candy.new.land #Outputs Hello
The definition of the "homer" method is adding the method to the Object class. It is not defining a free function.
Class Candy implicitly inherits from Object, and so has access to the methods in Object. When you call "homer" in the "land" method, the method resolution can't find a definition in the current class, goes to the super class, finds the method you have added to Object, and calls it.
A simple way to find out what happens
What classes/modules are searched to resolve methods used in Candy objects?
p Candy.ancestors #=> [Candy, Object, Kernel]
Does Candy have method called homer?
p Candy.instance_methods(false).grep("homer") #=> []
p Candy.private_instance_methods(false).grep("homer") #=> []
OK Candy does not have any method called 'homer'.
What's next in the lookup chain (see 1) => "Object"
Does Object have a method called "homer" ?
p Object.instance_methods(false).grep("homer") #=> []
p Object.private_instance_methods(false).grep("homer") #=> ["homer"]
Candy has Object in its lookup chain which in turn has a private instance method "homer" so method resolution succeeds
The def statement always defines the method in the class of whatever self is at the point of definition
What is self just before homer is defined ?
p self #=> main
def homer
puts "Hello"
end
So what is its type ?
p self.class #=> Object
Which is why homer ends up on Object
Technically, the definition of the homer method is actually on the Kernel module which is mixed into Object, not on Object directly. So when homer is not a local variable or an instance method defined on Candy, the Ruby method inheritance chain is followed up through Object and then to the mixed-in Kernel module and then this code is run.
Edit: Sorry, I don't know why I thought this. It appears that the method really lives on Object. Not sure it makes too much of a difference in practice but I should have confirmed things before posting.
Ruby has no free-floating functions. Every method belongs to some object. Methods that you def at the top level are actually becoming instance methods of class Object. Because everything is an Object at some level, all objects have access to Object's instance methods.