ActiveSupport mette a disposizione numerose estensioni interessanti volte ad ampliare le funzioni delle librerie Class e Module. Conoscerle è molto utile poiché queste due librerie sono alla base di tutti gli oggetti Ruby. Una qualsiasi classe Ruby, infatti, è a sua volta un oggetto discendente dalla classe Class. Gli oggetti di tipo Module invece sono spesso usati come Mixin e possono influenzare, direttamente o indirettamente, il comportamento di un qualsiasi oggetti in Ruby.
class Foo end module Bar end f = Foo.new f.class# => Foo Foo.class # => Class Bar.class # => Module
Ruby fornisce tre metodi per generare rapidamente i metodi setter e getter per una variabile d'istanza di una classe. Questi metodi si chiamano attr_reader, attr_writer e attr_accessor. ActiveSupport mette a disposizione altrettanti metodi per generare metodi accessori per accedere alle variabili d'istanza di una classe e di un modulo.
require '../helper' class MyClass @@foo = 'my foo' @@bar = 'my var' end begin puts MyClass.foo rescue NoMethodError => e puts 'Error: ' + e.message end begin MyClass.foo = 'new value' rescue NoMethodError => e puts 'Error: ' + e.message end class MyClass cattr_accessor :foo cattr_accessor :qui, :quo, :qua cattr_reader:bar end MyClass.bar # => 'bar' MyClass.foo = 'new value' MyClass.foo # => 'new value' module MyModule mattr_accessor :foo end MyModule.foo = ['foo', 'bar', 'bar'] MyModule.foo.inspect # => ["foo", "bar", "bar"]
Inoltre, in Module è dichiarato anche uno speciale metodo attr_accessor_with_default. Poiché Class è una speciale variante di Module, entrambi dispongono del metodo così come ogni classe in Ruby e le rispettive istanze.
require '../helper' class MyClass attr_accessor_with_default :color, 'red' end instance = MyClass.new instance.color # => 'red' instance.color = 'blue' instance.color # => 'blue'
Come noto, in Ruby il valore di una variabile di classe è automaticamente propagato a tutte le classi che la estendono. Se il valore varia in una qualsiasi delle classi, la modifica è propagata a tutto il ramo della gerarchia. ActiveSupport introduce la possibilità di definire variabili di classe il cui valore è copiato nelle classi figlie e non condiviso.
require '../helper'
class Polygon
cattr_accessor :angles
self.angles = 0
def self.count_angles
puts "#{self.name} has #{self.angles} angles."
end
end
puts Polygon.count_angles # => Polygon has 0 angles.
class Triangle < Polygon
self.angles = 3
end
Polygon.count_angles # => Polygon has 3 angles.
Triangle.count_angles # => Triangle has 3 angles.
class SafePolygon
class_inheritable_accessor :angles
self.angles = 0
def self.count_angles
puts "#{self.name} has #{self.angles} angles."
end
end
SafePolygon.count_angles # => SafePolygon has 0 angles.
class SafeTriangle < SafePolygon
self.angles = 3
end
SafePolygon.count_angles # => SafePolygon has 0 angles.
SafeTriangle.count_angles # => SafeTriangle has 3 angles.
Ci sono numerose altre chicche interessanti nascoste nelle estensioni per Module e Class, specialmente legate a caratteristiche e funzioni della programmazione ad oggetti come Delegazione, Inclusione, Introspezione e Metaprogrammazione. È interessante aprire il sorgente e curiosare all'interno delle varie implementazioni.
Se vuoi aggiornamenti su Development inserisci la tua email nel box qui sotto: