Introduction to Ruby’s Reflection API                             - Niranjan Sarade
Reflectiona.k.a. IntrospectionA program can examine its state and structureA program can alter its state and structureRuby...
Determine type of an objecto.class #=> Returns the class of an object cc.superclass #=> Returns the superclass of a class ...
module Cendclass A include Cendclass B < Aenda = A.newa.instance_of?(A) #=> trueb = B.newb.instance_of?(B) #=> trueb.insta...
o = “niranjan”o.class #=> Stringo.class.superclass #=> Objecto.class.superclass.superclass #=> nil : Object has no supercl...
Ancestors of class or modulemodule A; endmodule B; include A; endclass C; include B; endC < B #=> true : C includes BB < A...
Module.nestingmodule M   class C             Module.nesting #=> [M::C, M]      endendThe class method Module.nesting retur...
Variables and Constants- global_variables- local_variables- instance_variables- class_variables- constantsThese methods ex...
Querying, setting, removing and testing variablesLocal variables :-x=1eval(“x”) #=> 1eval(“x = 2”)eval(“x”)Instance variab...
Continued…Constants :-Math.const_set(:EPI, Math::E*Math::PI)Math.const_get(:EPI) #=> 8.539…Math.const_defined? :EPI #=> tr...
Listing and testing methodso = “test”o.methods #=> [ names of all public methods ]o.public_methods #=> same as aboveo.publ...
Define, undefine and alias methodsdefine_method –> private instance method of Module class# add an instance method names m...
Continued…undef method_nameremove_method or undef _method => private methods of Module classremove_method removes the defi...
AliasingA more practical reason for aliasing methods is to insert new functionality into amethod – augmenting existing met...
Method lookup or method name resolution algorithmFor method invocation expression o.m, Ruby performs name resolution with ...
e.g. “hello”.world1.   Check the eigenclass for singleton methods.2.   Check the String class. There is no instance method...
Thank you !
Upcoming SlideShare
Loading in …5
×

Introduction to Ruby’s Reflection API

6,026 views

Published on

This ppt is an introduction to Ruby's reflection API with examples.
(Reference :- 'Ruby Cookbook' book.)

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,026
On SlideShare
0
From Embeds
0
Number of Embeds
18
Actions
Shares
0
Downloads
21
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Introduction to Ruby’s Reflection API

  1. 1. Introduction to Ruby’s Reflection API - Niranjan Sarade
  2. 2. Reflectiona.k.a. IntrospectionA program can examine its state and structureA program can alter its state and structureRuby’s reflection API is rich and most of the methods are defined by Kernel,Object and Module
  3. 3. Determine type of an objecto.class #=> Returns the class of an object cc.superclass #=> Returns the superclass of a class co.instance_of? c #=> Determines whether the object o.class == co.is_a? c or o.kind_of? c#=> determines o is an instance of c or any of its subclasses. If c is a module, then this method tests whether o.class (or any of its ancestors) includes this module.c === o#=> For any class or module c, determines if o.is_a?(c)o.respond_to? Name#=> Determines whether the object has public or protected method with the specified name. Pass true as 2nd parameter to check private methods as well
  4. 4. module Cendclass A include Cendclass B < Aenda = A.newa.instance_of?(A) #=> trueb = B.newb.instance_of?(B) #=> trueb.instance_of?(A) #=> false #=> instance_of? does not check inheritenceb.is_a?(A) #=> trueb.is_a?(B) #=> trueb.is_a?(C) #=> trueB.is_a?(A) #=> falseA.is_a?(A) #=> false
  5. 5. o = “niranjan”o.class #=> Stringo.class.superclass #=> Objecto.class.superclass.superclass #=> nil : Object has no superclass# Ruby 1.9 onlyObject.superclass #=> BasicObjectBasicObject.superclass #=> nil
  6. 6. Ancestors of class or modulemodule A; endmodule B; include A; endclass C; include B; endC < B #=> true : C includes BB < A #=> trueC < A #=> trueString < Numeric #=> nil: strings are not numbersA.ancestors #=> [A]B.ancestors #=> [B, A]C.ancestors #=> [C, B, A, Object, Kernel]String.ancestors #=> [String, Comparable, Object, Kernel]C.include?(B) #=> true (public instance method defined by the Module class)C.include?(A) #=> trueB.include?(A) #=> trueA.include?(A) #=> falseA.include?(B) #=> falseA.included_modules #=> [ ]B.included_modules #=> [A]C.included_modules #=> [B, A, Kernel]
  7. 7. Module.nestingmodule M class C Module.nesting #=> [M::C, M] endendThe class method Module.nesting returns nesting of modules at the currentlocation.Module.nesting[0] => current class or moduleModule.nesting[1] => containing class or module
  8. 8. Variables and Constants- global_variables- local_variables- instance_variables- class_variables- constantsThese methods except local_variables return array of strings in Ruby 1.8 andarray of symbols in Ruby 1.9.The local_variables method returns an array of strings in both versions of Ruby.
  9. 9. Querying, setting, removing and testing variablesLocal variables :-x=1eval(“x”) #=> 1eval(“x = 2”)eval(“x”)Instance variables :-o = Object.newo.instance_variable_set(:@x, 10)o.instance_variable_get(:@x) #=> 10o.instance_variable_defined?(:@x) #=> trueClass variables :-Object.class_variable_set(:@@x, 5) #=> Private in Ruby 1.8Object.class_variable_get(:@@x) #=> 5 ; Private in Ruby 1.8Object.class_variable_defined?(:@@x) #=> true; Ruby 1.9 and later
  10. 10. Continued…Constants :-Math.const_set(:EPI, Math::E*Math::PI)Math.const_get(:EPI) #=> 8.539…Math.const_defined? :EPI #=> trueIn Ruby 1.9, we can pass ‘false’ as 2nd argument to const_get and const_defined?to specify that these methods should only look at the current class or module and shouldnot consider inherited constants.Object and Module define private methods for undefining instance variables, classvariables and constants. (Use eval or send to invoke these methods)They return the value of the removed variable or constant.o.instance_eval {remove_instance_variable(:@x)}String.class_eval {remove_class_variable (:@@x)}Math.send :remove_const, :EPI
  11. 11. Listing and testing methodso = “test”o.methods #=> [ names of all public methods ]o.public_methods #=> same as aboveo.public_methods(false) #=> Exclude inherited methodso.protected_methods #=> [ ]o.private_methods #=> array of all private methodso.private_methods(false) #=> Exclude inherited private methodsdef o.single; 1; end # define a singleton methodo.singleton_methods #=> *“single”+String.instance_methods == “s”.public_methods #=> trueString.instance_methods(false) == “s”.public_methods(false) #=> trueString.public_instance_methods == String.instance_methods #=> trueString.protected_instance_methods #=> []String.private_instance_methods(false) #=> *“initialize_copy”, “initialize”+The class methods of a class or module are singleton methods of the Class or Module object. So to listthe class methods, use Object.singleton_methods:Math.singleton_methods #=> *“acos”, “log10”, …+
  12. 12. Define, undefine and alias methodsdefine_method –> private instance method of Module class# add an instance method names m to class c with body bdef add_method(c,m,&b) c.class_eval { define_method(m,&b) }endadd_method(String, :greet) ,‘Hello’ + self-‘world’.greet #=> ‘Hello world’To create a synonym or an alias for an existing method :-alias plus + # make plus a synonym for the + operator (2 identifiers to be hardcoded)Oralias_method # private instance method of Module class (dynamic programming)
  13. 13. Continued…undef method_nameremove_method or undef _method => private methods of Module classremove_method removes the definition of the method from the current classIf there is a version defined by a superclass, that version now will be inherited.undef_method prevents any invocation of the specified method through aninstance of the class, even if there is an inherited version of that method.
  14. 14. AliasingA more practical reason for aliasing methods is to insert new functionality into amethod – augmenting existing methodsdef hello p ‘hello’endalias original_hello hellodef hello p ‘some stuff’ original_hello p ‘some more stuff’end
  15. 15. Method lookup or method name resolution algorithmFor method invocation expression o.m, Ruby performs name resolution with the followingsteps :-1. First, it checks the eigenclass of o for singleton methods named m2. If no method m is found in the eigenclass, ruby searches the class of o for an instance method named m3. If not found, ruby searches the instance methods of any modules included by the class of o. If that class includes more than one module, then they are searched in the reverse of the order in which they were included. i.e. the most recently included module is searched first.4. If not found, then the search moves up the inheritance hierarchy to the superclass. Steps 2 and 3 are repeated for each class in the inheritance hierarchy until each ancestor class and its included modules have been searched.5. If not found, then method_missing is invoked instead. In order to find an appropriate definition of this method, the name resolution algorithm starts over at step 1. The Kernel module provides a default implementation of method_missing, so this second pass of name resolution is guaranteed to succeed.6. This may seem like it requires ruby to perform an exhaustive search every time it invokes a method.7. However, successful method lookups will be cached so that subsequent lookups of the same name will be very quick.
  16. 16. e.g. “hello”.world1. Check the eigenclass for singleton methods.2. Check the String class. There is no instance method named ‘world’.3. Check the Comparable and Enumerable modules of the String class for an instance method named ‘world’.4. Check the superclass of String, which is Object.5. Look for method_missing in each of the spots above. The first definition of method_missing we find id in the Kernel module, so this method gets invoked.6. It raises an exception NoMethodError : undefined method ‘world’ for “hello”:String.7. However, successful method lookups will be cached so that subsequent lookups of the same name will be very quick.
  17. 17. Thank you !

×