Subsecciones


Creando Clases con Struct

$ cat -n struct_point.rb 
     1  Point = Struct.new(:x, :y)   # Creates new class, assigns to Point
     2  
     3  p = Point.new(1,2)   # => #<struct Point x=1, y=2>
     4  p p.x                  # => 1·
     5  p p.y                  # => 2
     6  p.x = 3                # => 3
     7  p p.x                  # => 3
     8  #---------------------------
     9  p[:x] = 7         
    10  p p[:x]              # => 7: same as p.x
    11  p p[1]               # => 2: same as p.y
    12  p.each {|c| print c}  # prints "72"
    13  puts
    14  p.each_pair {|n,c| print n,c; puts } 
    15  puts
    16  #---------------------------
    17  p = Point.new(4,2)
    18  q = Point.new(4,2)
    19  p q == p        # => true
    20  h = {q => 1}  # Create a hash using q as a key
    21  p h[p]          # => 1: extract value using p as key
    22  p q.to_s        # => "#<struct Point x=4, y=2>"
    23  
    24  require 'extending_struct_point'
    25  
    26  puts "sorting!"
    27  puts [p, q].sort

Extendiendo clases creadas con Struct

Por supuesto podemos abrir la clase creada con Struct y extenderla:
$ cat -n extending_struct_point.rb 
     1  class Point                  # Open Point class for new methods
     2    def add!(other)            # Define an add! method
     3      self.x += other.x
     4      self.y += other.y
     5      self
     6    end
     7  
     8    include Comparable         # Include a module for the class
     9    def <=>(other)             # Define the <=> operator
    10      return nil unless other.instance_of? Point
    11      self.x**2 + self.y**2 <=> other.x**2 + other.y**2
    12    end
    13  end

$ ruby -I. struct_point.rb 
1
2
3
7
2
72
x7
y2

false
nil
"#<struct Point x=4, y=2>"
sorting!
#<struct Point x=4, y=2>
#<struct Point x=7, y=2>

haciendo Inmutable una clase creada con Struct

Las clases creadas por Struct son mutables. Si la queremos hacer inmutable usamos undef:

$ cat -n making_struct_inmutable.rb 
     1  Point = Struct.new(:x, :y)  # Define mutable class
     2  class Point                 # Open the class
     3    undef x=,y=,[]=           # Undefine mutator methods
     4  end
     5  
     6  z = Point.new(2,3)
     7  
     8  z.x = 4

[~/point]$ ruby making_struct_inmutable.rb 
making_struct_inmutable.rb:8:in `<main>': 
  undefined method `x=' for #<struct Point x=2, y=3> (NoMethodError)

Casiano Rodriguez León 2015-06-18