CSC/ECE 517 Fall 2012/ch1b 1w57 mp: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(16 intermediate revisions by the same user not shown)
Line 8: Line 8:
In Ruby, classes are never closed: you can always add methods to an existing class. This applies to the classes you write as well as the standard, built-in classes. All you have to do is open up a class definition for an existing class, and the new contents you specify will be added to whatever's there.
In Ruby, classes are never closed: you can always add methods to an existing class. This applies to the classes you write as well as the standard, built-in classes. All you have to do is open up a class definition for an existing class, and the new contents you specify will be added to whatever's there.
Comparing this to other object oriented languages like JAVA, we cannot modify the existing standard classes and add custom methods. We will have to create a new class of our own which inherits from the standard class and add new functionalities to it. Then, we need to use this user-defined class in place of the standard class.
Comparing this to other object oriented languages like JAVA wherein we cannot modify the existing standard classes and add custom methods. We will have to create a new class of our own which inherits from the standard class and add new functionalities to it. Then, we need to use this user-defined class in place of the standard class.
===Implementing custom methods in Open Classes===
===Implementing custom methods in Open Classes===
As an example of Open Classes explained above, consider the functionality of converting Euros to Dollars.
As an example of Open Classes explained above, consider the functionality of converting Euros to Dollars.
<Code>
Example:
class Numeric
 
def euros ; self * 0.019; end # custom method defined here.
        class Numeric
end
                def euros ; self * 0.019; end # custom method defined here.
        end
class Bank
        class Bank
..
            ..
account.deposit(20.euros) # call to custom method.
            account.deposit(20.euros) # call to custom method.
..
            ..
end
        end
</Code>
Here, we define our own method 'euros' by extending the Numeric class. Euro-to-Dollar conversion can then be done by invoking the euros method as shown above.
Here, we define our own method 'euros' by extending the Numeric class. Euro-to-Dollar conversion can then be done by invoking the euros method as shown above.
===Method Missing===
===Method Missing===
When you send a message to an object, the object executes the first method it finds on its method lookup path with the same name as the message. If it fails to find any such method, it raises a NoMethodError exception - unless you have provided the object with a method called method_missing. The method_missing method is passed the symbol of the non-existent method, an array of the arguments that were passed in the original call and any block passed to the original method.
When you send a message to an object, the object executes the first method it finds on its method lookup path with the same name as the message. If it fails to find any such method, it raises a NoMethodError exception - unless you have provided the object with a method called method_missing. The method_missing method is passed the symbol of the non-existent method, an array of the arguments that were passed in the original call and any block passed to the original method.
If we extend the previous example to define method_missing for the Numeric class,//1.euro we can do it as shown:
If we extend the previous example to define method_missing for the Numeric class, we can do it as shown.
 
class Numeric
Example:
def method_missing(method_id)
 
if method_id.to_s == "euro"
        class Numeric
self.send('euros')
                def method_missing(method_id)
else
                        if method_id.to_s == "euro"
super
                                self.send('euros')
end
                        else
end
                                super
                        end
def euros
                end
..
                def euros
end
                        ..
end
                end
        end
The above implementation of Numeric class allows calling euros as well as the euro method(since 1.euro is more appropriate). Here, since euro is not defined, method missing is passed the name of the method that does not exist: "euro" which can then be used to call the 'euros' method through self.send. Furthermore, if this is not defined, then the control is transfered to the parent class.  
The above implementation of Numeric class allows calling euros as well as the euro method(since 1.euro is more appropriate). Here, since euro is not defined, method missing is passed the name of the method that does not exist: "euro" which can then be used to call the 'euros' method through self.send. Furthermore, if this is not defined, then the control is transfered to the parent class.  


==Summary==
==Summary==
Line 54: Line 55:
==References==
==References==
http://rubylearning.com/blog/2010/11/23/dont-know-metaprogramming-in-ruby/
#http://rubylearning.com/blog/2010/11/23/dont-know-metaprogramming-in-ruby/
http://rubylearning.com/satishtalim/ruby_open_classes.html
#http://rubylearning.com/satishtalim/ruby_open_classes.html
http://rubylearning.com/satishtalim/ruby_method_missing.html
#http://rubylearning.com/satishtalim/ruby_method_missing.html


==Further Reading==
==Further Reading==
http://ruby-doc.org/docs/ProgrammingRuby/
#http://ruby-doc.org/docs/ProgrammingRuby/
http://en.wikipedia.org/wiki/Ruby_(programming_language)
#http://en.wikipedia.org/wiki/Ruby_(programming_language)
http://rubymonk.com/
#http://rubymonk.com/
http://www.ruby-lang.org/en/documentation/quickstart
#http://www.ruby-lang.org/en/documentation/quickstart
http://www.ruby-doc.org/downloads/
#http://www.ruby-doc.org/downloads/

Latest revision as of 01:26, 4 October 2012

Introduction

One of the most impressive aspects of Ruby is its metaprogramming capabilities. As a dynamic language, Ruby gives you the freedom to define methods and even classes during runtime. Metaprogramming with Ruby, one can do in a few minutes what other languages may take hours to do. By cleverly planning your code and applying the techniques mentioned here, you’ll be able to write code that is DRYer, lighter, more intuitive and more scalable.

Metaprogramming in Ruby

Open Classes

In Ruby, classes are never closed: you can always add methods to an existing class. This applies to the classes you write as well as the standard, built-in classes. All you have to do is open up a class definition for an existing class, and the new contents you specify will be added to whatever's there.

Comparing this to other object oriented languages like JAVA wherein we cannot modify the existing standard classes and add custom methods. We will have to create a new class of our own which inherits from the standard class and add new functionalities to it. Then, we need to use this user-defined class in place of the standard class.

Implementing custom methods in Open Classes

As an example of Open Classes explained above, consider the functionality of converting Euros to Dollars.

Example:

       class Numeric
               def euros ; self * 0.019; end		# custom method defined here.
       end
       class Bank
            ..
            account.deposit(20.euros)			# call to custom method.
            ..
       end

Here, we define our own method 'euros' by extending the Numeric class. Euro-to-Dollar conversion can then be done by invoking the euros method as shown above.

Method Missing

When you send a message to an object, the object executes the first method it finds on its method lookup path with the same name as the message. If it fails to find any such method, it raises a NoMethodError exception - unless you have provided the object with a method called method_missing. The method_missing method is passed the symbol of the non-existent method, an array of the arguments that were passed in the original call and any block passed to the original method.

If we extend the previous example to define method_missing for the Numeric class, we can do it as shown.

Example:

       class Numeric
               def method_missing(method_id)
                       if method_id.to_s == "euro"
                               self.send('euros')
                       else
                               super
                       end
               end
               def euros
                       ..
               end
       end

The above implementation of Numeric class allows calling euros as well as the euro method(since 1.euro is more appropriate). Here, since euro is not defined, method missing is passed the name of the method that does not exist: "euro" which can then be used to call the 'euros' method through self.send. Furthermore, if this is not defined, then the control is transfered to the parent class.

Summary

All the classes in Ruby are open which allow you to define custom methods. To make code more readable, it is okay to reopen the standard classes to define custom methods. These features saves a lot of effort in Ruby compared to other Object Oriented languages like JAVA, C++

References

  1. http://rubylearning.com/blog/2010/11/23/dont-know-metaprogramming-in-ruby/
  2. http://rubylearning.com/satishtalim/ruby_open_classes.html
  3. http://rubylearning.com/satishtalim/ruby_method_missing.html

Further Reading

  1. http://ruby-doc.org/docs/ProgrammingRuby/
  2. http://en.wikipedia.org/wiki/Ruby_(programming_language)
  3. http://rubymonk.com/
  4. http://www.ruby-lang.org/en/documentation/quickstart
  5. http://www.ruby-doc.org/downloads/