Presentation is loading. Please wait.

Presentation is loading. Please wait.

types in Ruby and other languages…

Similar presentations


Presentation on theme: "types in Ruby and other languages…"— Presentation transcript:

1 types in Ruby and other languages…
Classes and Objects types in Ruby and other languages…

2 Language Design - classes
Classes and objects (vs prototypes) Instance variables/encapsulation Object creation Object equality/comparison Object type type-safety type conversions Class methods Class variables Inheritance – another lecture

3 Encapsulation Protect instance variables from outside forces (i.e., other classes) Ruby is strictly encapsulated always private you must include setters/getter as long as other classes can’t access data directly, it’s encapsulated Reflection and open classes (covered later) subvert this encapsulation

4 Compare to Java package by default can declare public
best practice: make instance variables private why? provides data validity (can only update via setter) if you want to change internal data representation later, easy to do (other code accesses via getter… ) Based on above, Java is not strictly encapsulated

5 Object creation Every class inherits method new
calls allocate to get space (can’t override) calls initialize to create instance variables Often convenient to provide default parameters for initialize def initialize(x, y, z=nil) @x, = x,y,z end

6 Simple Class new calls initialize to_s like toString
class Cat def = name, age end def to_s def def def def c = Cat.new("Fluffy", 2) puts c puts c.name c.age=5 puts c.age puts c.to_s new calls initialize to_s like toString getters and setters, called attributes last expression in function is return @ indicates instance variable always refer to self DO NOT declare outside of method

7 Operator Overloading, etc.
class Bottle attr_accessor :ounces attr_reader :label def initialize(label, = = ounces end def def += other.ounces other.ounces = 0 def split(scalar) newOunces / -= newOunces newOunces) def + amount) def to_s # with an accessor, don't - why? "(#{label}, #{ounces})" b = Bottle.new("Tab", 16) puts b.label b.ounces = 20 puts "b is #{b}“ puts "result of b2 = b.split 4" b2 = b.split 4 puts "b is #{b}" puts "b2 is #{b2}“ puts "result of b3 = b.add(b2)" b3 = b.add(b2) puts "b3 is #{b3}“ puts "result of b.add!(b2)" b.add!(b2) puts "result of b4 = b3 + 10" b4 = b puts "b4 is #{b4}" attr is example of metaprogramming

8 Polymorphism From wikipedia:
Polymorphism (from the Greek many forms) is the provision of a single interface to entities of different types. A polymorphic type is one whose operations can also be applied to values of some other type, or types. We’ll see 3 types of polymorphism: Ad hoc (e.g., operator overloading) Parametric (e.g., generics in Java, duck typing in Ruby) Subtyping (e.g., parent-child relationships where child overrides parent methods)

9 Ad hoc Polymorphism If a function denotes different and potentially heterogeneous implementations depending on a limited range of individually specified types and combinations, it is called ad hoc polymorphism. Ad hoc polymorphism is supported in many languages using function overloading. i.e., same function name, but behavior is different depending on number and/or types of parameters Why would this be called ad hoc? See also:

10 Parametric Polymorphism
If the code is written without mention of any specific type and thus can be used transparently with any number of new types, it is called parametric polymorphism. without any specific type, but potentially with a type parameter e.g., LinkedList<T> we explored this briefly in prior lecture In the object-oriented programming community, this is often known as generics or generic programming. See also:

11 Duck Typing class Can attr_accessor :ounces def initialize(label, = = ounces end def to_s b = Bottle.new("Tab", 16) c = Can.new(“Coke", 12) b2 = b.add(c) puts "result of b2 = b.add(c)" puts "b2 is #{b2}“ cat = Cat.new b3 = b.add(cat) If it walks like a duck and quacks like a duck, it must be a duck any object with needed method will work undefined method ‘ounces’ for <Cat>

12 Object Class x=1 x.instance_of? Fixnum => true
x.instance_of? Numeric => false (even though subclass) x.is_a? Fixnum => true x.is_a? Numeric => true x.is_a? Comparable => true x.is_a? Object => true x.class == Fixnum => true x.class == Numeric => false Quick Ex: how does Java handle?

13 Object Type Class of an object doesn’t change
Type is more fluid… includes set of behaviors (methods it responds to) i.e, Class != Type….whoaaa respond_to?

14 Object equality equal? checks addresses (like == in Java)
for Object, == is synonym for equal? Most classes override == (like equal in Java) POPL goal: be aware of features that commonly exist in many/all languages BUT have subtle differences

15 Equality Example class Bottle attr_accessor :ounces attr_reader :label def initialize(label, = = ounces end def ==(other) return false if ! other.instance_of? Bottle == other.ounces == other.label alias eql? == # Can also has ounces class Can b = Bottle.new("Tab", 16) b2 = Bottle.new("Tab", 16) b3 = Bottle.new("Tab", 12) b4 = Bottle.new("Coke", 16) puts "b.equal?(b2) #{b.equal?(b2)}" puts "b == b2 #{b == b2}" puts "b == b3 #{b == b3}" puts "b == b4 #{b == b4}“ puts "b.eql?(b2) #{b.eql?(b2)}" puts "b.eql?(b3) #{b.eql?(b3)}" c = Can.new("Tab", 16) puts "b == c #{b == c}"

16 More object equality Numeric classes will do type conversions when used with == eql? is like ==, but no type conversion 1.eql? 1.0 can alias eql? with ==

17 More object comparison
=== used with case statement (1..10) === 5 # true, 5 is in range /\d+/ === “123” # true, matches regex String === “s” # true if s is instance of String Interesting option that provides a context-sensitive comparison, but we won’t study/make use of

18 Type-safe Methods class Bottle attr_accessor :ounces attr_reader :label def initialize(label, = = ounces end def add(other) raise TypeError, "Bottle argument expected " unless other.is_a? def add2(other) raise TypeError, "Bottle argument expected " unless other.respond_to? :ounces def add3(other) rescue raise TypeError, "Cannot add with an argument that doesn't have ounces" def to_s class Can attr_accessor :ounces def initialize(label, = = ounces end def to_s class Cat b = Bottle.new("Tab", 16) c = Can.new("Coke", 12) puts "result of b2 = b.add(c)" b2 = b.add(c) puts "result of b2 = b.add2(c)" b2 = b.add2(c) puts "b2 is #{b2}" puts "result of b2 = b.add3(c)" b2 = b.add3(c) cat = Cat.new puts "result of b2 = b.add3(cat)" b2 = b.add3(cat)

19 More overloading class Bottle attr_accessor :ounces attr_reader :label def initialize(label, = = ounces end def each def [](index) case index when 0, -2 when 1, -1 when :label, "label" when :ounces, "ounces" b = Bottle.new("Tab", 16) puts "using each" b.each {|x| puts x } puts "[ix]" puts b[0] puts b[-2] puts b[1] puts b[-1] puts "[field name]" puts b["label"] puts b[:label] puts b["ounces"] puts b[:ounces]

20 Object Comparisons Implement <=> operator (spaceship)
Like compareTo (-1, 0, 1 and nil if not comparable) Typically include Comparable module as a mixin Provides <, <=, ==, >=, >(defined in terms of <=>) Sometimes write == anyway (e.g., one may be case-sensitive, may be more efficient). Best to be consistent.

21 Comparison example class Bottle include Comparable attr_accessor :ounces attr_reader :label def initialize(label, = = ounces end def hash #based on Effective Java by Bloch code = 17 code = 37 * code code = 37 * code code def <=>(other) return nil unless other.instance_of? <=> other.ounces b = Bottle.new("Tab", 16) b2 = Bottle.new("Tab", 12) b3 = Bottle.new("Coke", 16) b4 = Bottle.new("Tab", 16) puts "b == b2 #{b == b2}" puts "b < b2 #{b < b2}" puts "b > b2 #{b > b2}" puts "b == b3 #{b == b3}" puts "b == b4 #{b == b4}"

22 Class Methods and variables
class Bottle include Comparable attr_accessor :ounces attr_reader :label MAX_OUNCES = 64 = 0 def initialize(label, = label += 1 if ounces > = MAX_OUNCES = ounces end def Bottle.sum(bottles) total = 0 bottles.each {|b| total += b.ounces } total def to_s def self.report #class method puts "Number of bottles created: bottles = Array.new bottles[0] = Bottle.new("Tab", 16) bottles[1] = Bottle.new("Tab", 16) bottles[2] = Bottle.new("Coke", 16) bottles[3] = Bottle.new("Tab", 20) puts "Total ounces: #{Bottle.sum bottles}" b = Bottle.new("Sprite", 72) puts b Bottle.report Not covered: Class Instance Variables

23 Topic Summary Language Concepts Ruby Classes Instance variables
Object creation Determine object type Object equality Object comparisons Type conversions Type safety Class methods – next lecture Class variables Ruby new to_s duck typing

24 Additional Topics Not covered, but may be useful dup clone
initialize_copy marshalling (create from serialized data)


Download ppt "types in Ruby and other languages…"

Similar presentations


Ads by Google