Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Class e module

Estensioni che permettono di estendere i le librerie Class e Module
Estensioni che permettono di estendere i le librerie Class e Module
Link copiato negli appunti

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.


Ti consigliamo anche