CSC/ECE 517 Fall 2007/wiki1b 1 c4: Difference between revisions
(12 intermediate revisions by the same user not shown) | |||
Line 15: | Line 15: | ||
===What is it?=== | ===What is it?=== | ||
A section of code that does or performs a task and then returns a value. A synonym for a method is a function. Methods can also be included within classes and used as accessors, mutators and setters.[2] Methods are created with the keyword ''def'' | A section of code that does or performs a task and then returns a value. A synonym for a method is a function. Methods can also be included within classes and used as accessors, mutators and setters.[2] Methods are created with the keyword ''def'' then the name of the method and end with the keyword ''end''. A method is called by simply typing the name of the method and enclosing any parameters to the method in "()". i.e. some_method(some_parameter).[1] | ||
===General Rule For Multiple Methods=== | ===General Rule For Multiple Methods=== | ||
If multiple methods with are defined with the same name and a call is made to that method, Ruby will look in the immediate class of an object first for the method definition. It then will look in any mixins included within the class and lastly in any superclasses and their mixins. If multiple mixins are present the rule for searching is that the last one included will be search first.[1] | If multiple methods with are defined with the same name and a call is made to that method, Ruby will look in the immediate class of an object first for the method definition. It then will look in any mixins included within the class and lastly in any superclasses and their mixins. If multiple mixins are present the rule for searching is that the last one included will be search first.[1] | ||
==Unexpected Behavior of a Module when New Method with Same Name was Added.== | |||
When a method is added to a module and the new method that happens to conflict with a name of an existing method the method last defined takes presidence. | |||
This creates an unexpected behavior if you call the method and are expecting the original method to be called. | |||
===Example=== | |||
module Hello | |||
def hello_world | |||
puts "Hello World" | |||
end | |||
def hello_world | |||
puts "Hello Worlds" | |||
end | |||
end | |||
class Test | |||
include Hello; | |||
end | |||
testObject = Test.new | |||
testObject.hello_world | |||
Output: | |||
Hello Worlds | |||
==Resolving Ambiguity with Qualified Naming== | ==Resolving Ambiguity with Qualified Naming== | ||
Line 47: | Line 79: | ||
To truly take out all ambiguity you would need to also alias all methods within the module. If this is done properly then the multiple method rule will not need to be used. Each method in both modules and classes would be referenced by there alias name which will point it to the correct method. The class could now have any number of modules included or any number of superclasses and still keeping with good object oriented programming.[4] | To truly take out all ambiguity you would need to also alias all methods within the module. If this is done properly then the multiple method rule will not need to be used. Each method in both modules and classes would be referenced by there alias name which will point it to the correct method. The class could now have any number of modules included or any number of superclasses and still keeping with good object oriented programming.[4] | ||
===Negatives=== | ===Negatives=== | ||
Line 59: | Line 91: | ||
The best object oriented design approach would be to to make method names longer and descriptive. By not given into the temptation to give simplistic names for methods you decrease the odds of ambiguity occurring when u mixin modules and inherit from classes. Descriptive method names must be done to all methods in modules and classes. This is a great way to maintain good object oriented design as you are able to still use modules and classes and still include those in classes without the worry of ambiguity.[4] | The best object oriented design approach would be to to make method names longer and descriptive. By not given into the temptation to give simplistic names for methods you decrease the odds of ambiguity occurring when u mixin modules and inherit from classes. Descriptive method names must be done to all methods in modules and classes. This is a great way to maintain good object oriented design as you are able to still use modules and classes and still include those in classes without the worry of ambiguity.[4] | ||
===Example=== | |||
def | def print_hello_World | ||
puts "Hello World" | |||
end | end | ||
def print_hello | |||
puts "Hello" | |||
end | |||
def add_two_numbers_together | |||
2+2 | |||
end | |||
==References== | ==References== | ||
Line 86: | Line 112: | ||
# http://www.geocities.com/eymiha/papers/HandlingForwardReferenceInRuby.html | # http://www.geocities.com/eymiha/papers/HandlingForwardReferenceInRuby.html | ||
# http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html | # http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html | ||
# http://zimbatm.oree.ch/2006/12/25/various-method-aliasing-methods-in-ruby | |||
# http://www.cosine.org/2007/08/30/method-aliasing-aspect-oriented-programming/ |
Latest revision as of 17:58, 10 October 2007
Introduction
Problem
If multiple methods with the same name are defined, there needs to be some way of determining which method a call refers to. The general rule is given on p. 123 of Programming Ruby. But questions still remain.
Questions
- Is it possible to get unexpected behavior if one of the modules you are using is "enhanced" to contain a new method that happens to conflict with a name of an existing method?
- Is it possible to refer to these methods using a qualified name?
- Is it possible to use method aliasing to resolve the ambiguity?
- What approach does good o-o design dictate?
Method
What is it?
A section of code that does or performs a task and then returns a value. A synonym for a method is a function. Methods can also be included within classes and used as accessors, mutators and setters.[2] Methods are created with the keyword def then the name of the method and end with the keyword end. A method is called by simply typing the name of the method and enclosing any parameters to the method in "()". i.e. some_method(some_parameter).[1]
General Rule For Multiple Methods
If multiple methods with are defined with the same name and a call is made to that method, Ruby will look in the immediate class of an object first for the method definition. It then will look in any mixins included within the class and lastly in any superclasses and their mixins. If multiple mixins are present the rule for searching is that the last one included will be search first.[1]
Unexpected Behavior of a Module when New Method with Same Name was Added.
When a method is added to a module and the new method that happens to conflict with a name of an existing method the method last defined takes presidence. This creates an unexpected behavior if you call the method and are expecting the original method to be called.
Example
module Hello
def hello_world puts "Hello World" end def hello_world puts "Hello Worlds" end
end
class Test
include Hello;
end
testObject = Test.new
testObject.hello_world
Output:
Hello Worlds
Resolving Ambiguity with Qualified Naming
Way it Works
If you have two classes and both have a method that has an identical name, then a fully qualified named will take care of any ambiguity in this situation. For example objectOne.someMethod will be different than objectTwo.someMethod assuming that objectOne and objectTwo are different class types.
When dealing with both mixins and classes, ambiguity can be resolved in a similar way that is done with classes. If you have two modules that both have a method that has an identical name and each module are included in different classes the qualified name as stated above will take care of the ambiguity.[5]
Problems
- If a class has a super class and the super class has a method that has the same name as one in the child class, then using the fully qualified name will not solve the issue.
- If a class has a module mixed in or included, and that mixin contains a method that has an identical name of one in the class, the qualified name will be confused and revert back to the multiple methods rule.
- If two mixins have a method with the same name and are included in the same class, ambiguity still exists.
Not A Good Idea
There are to many problems with using qualified names to handle multiple methods. Although they can be used in certain situations, there are many that they can't be used in. This creates a situation where qualified names aren't a recommended way to handle multiple methods.
Resolving Ambiguity with Method Aliasing
It Is Possible
It is possible to use method aliasing to resolve ambiguity. The odds of a class having two methods with the same name are very small. However aliasing will take care of if a module is included and the module contains a method that has the same name as a method within the class. You would now simply refer to the method in the class by the alias method and ambiguity is solved because the class definition is now independent on whether the module methods are aliased or not.
To truly take out all ambiguity you would need to also alias all methods within the module. If this is done properly then the multiple method rule will not need to be used. Each method in both modules and classes would be referenced by there alias name which will point it to the correct method. The class could now have any number of modules included or any number of superclasses and still keeping with good object oriented programming.[4]
Negatives
- Copies are created for each method that is aliased.[3] If you have 100 modules and 200 classes with 20 methods in each, then instead of 4000 methods you not have 8000 methods that have been defined and only half are unique. This is not good.
- If you are dealing with a large scale ruby project the number of aliases you have to deal with is enormous. Simply giving more descriptive method names would work better.
The Good Object Oriented Design Way
The best object oriented design approach would be to to make method names longer and descriptive. By not given into the temptation to give simplistic names for methods you decrease the odds of ambiguity occurring when u mixin modules and inherit from classes. Descriptive method names must be done to all methods in modules and classes. This is a great way to maintain good object oriented design as you are able to still use modules and classes and still include those in classes without the worry of ambiguity.[4]
Example
def print_hello_World puts "Hello World" end
def print_hello puts "Hello" end def add_two_numbers_together 2+2 end
References
- Programming Ruby: The Pragmatic Programmers' Guide
- http://en.wikibooks.org/wiki/Programming:Ruby_Method_Calls
- http://ruby.about.com/od/learnruby/qt/using_alias.htm
- http://www.geocities.com/eymiha/papers/HandlingForwardReferenceInRuby.html
- http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html
- http://zimbatm.oree.ch/2006/12/25/various-method-aliasing-methods-in-ruby
- http://www.cosine.org/2007/08/30/method-aliasing-aspect-oriented-programming/