Ruby - Colorado School of Mines
Download
Report
Transcript Ruby - Colorado School of Mines
Also “open class”
and other languages…
A
module is a named group of methods,
constants, and class variables
All classes are modules
Modules are not classes
• Can’t be instantiated
• Can’t be subclassed
Purpose: namespaces
and mixins
Object
Module
Class
Numeric
Integer
Fixnum
4
From: Seven Languages in Seven Weeks
Example: want
to provide utility functions
that don’t require an object. Maybe
encode/decode functions, conversions,
math functions, etc.
Can add global methods, but then need
to worry about naming conflicts.
Remember namespaces from C++?
module Base64
def self.encode (data)
# code here
end
#could be: Base64.decode
# cannot just leave off self
def self.decode (text)
# code here
end
end
Call as:
text = Base64.encode(data)
data = Base64.decode(text)
If
a module defines instance methods, those
can be “mixed into” other classes
Essentially eliminates need for multiple
inheritance
Examples:
• Enumerable. defines iterators that make use of each
method
• Comparable. defines comparison operators (<,
<=,==, >, >=, between?) in terms of <=> (like
compareTo)
Module.include
function does the “mixing”
How does this compare to Java Interface?
Quick
Exercise: take a look at:
• http://matt.aimonetti.net/posts/2012/07/30/ruby-class-module-
mixins/
• http://stackoverflow.com/questions/575920/is-a-ruby-moduleequivalent-to-a-java-interface
With
your partner:
• List a best practice for classes
• When does it make sense to write a module
instance method?
require brings in the contents of another file (like “include” in
C++)
include “mixes in” a module
module FlyingCreature
def Fly
end
end
class Bird
include FlyingCreature
#... end
class Bat < Mammal
include FlyingCreature
#... end
dracula = Bat.new
Notice that dracula.is_a? Mammal is true, and so is dracula.is_a? FlyingCreature.
RubyModules-2.rb demo code, example from:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/16071
Methods and variables
can be added to classes
In RubyOpenClasses-1.rb:
class Cat
attr_accessor :name, :age
def initialize(name, age)
@name, @age = name, age
end
end
In
another file:
require_relative "RubyOpenClasses-1.rb"
class Cat
def purr
puts "#{name} says Purrrrrrrrrrr"
end
end
ollie = Cat.new("Ollie", 5)
ollie.purr
http://stackoverflow.com/questions/4184821/do-rubys-open-classes-break-encapsulation
class Person
def initialize(name)
@name=name
end
end
shugo = Person.new("Shugo")
matz = Person.new("Matz")
def matz.design_ruby
puts "I am #{@name} and I designed Ruby!"
end
matz.design_ruby
shugo.design_ruby # error!
From: http://www.slideshare.net/ShugoMaeda/rc2010-refinements
Helps
to guide best practices for Ruby open
classes
LSP (as we know it): subtypes must be
substitutable for base class
• Goal: don’t break program when call a method that
expects a parent object but receives a child object
• Remember: square vs rectangle example.
LSP: instances
of a class after reopen must
behave like instances of a class before
From: http://www.slideshare.net/ShugoMaeda/rc2010-refinements
LSP Violation:
puts (1/2) => 0
NOW open file that requires "mathn"
puts (1/2) => (1/2)
What class was modified in this example?