Olá pessoal
Estou tentando implementar algo como pré e pós condições em ruby, para isso criei o método abaixo:
class Class
def attr_contract *args
args.each do |attr|
name = attr[:name]
pre = attr[:pre]
pos = attr[:pos]
pre_message = attr[:pre_message].nil? ? "Pre condiction violated (#{pre})" : attr[:pre_message]
pos_message = attr[:pos_message].nil? ? "Pos condiction violated (#{pos})" : attr[:pos_message]
m = ''
m << "def #{name}= value\n"
if pre
m << " raise StandardError.new('#{pre_message}') unless (#{pre})\n"
end
m << " @#{name} = value\n"
if pos
m << " raise StandardError.new('#{pos_message}') unless (#{pos})\n"
end
m << "end\n\n"
m << "def #{name}\n"
m << " @#{name}\n"
m << "end\n"
puts m
class_eval(m)
end
end
end
class Conta
attr_contract( { :name => :saldo,
:pre => 'ativa?',
:pos => 'value > 0',
:pre_message => 'Conta inativa!' ,
:pos_message => 'Saldo irregular para esta conta' } )
def initialize ativa, saldo_inicial
@ativa, @saldo_inicial = ativa, saldo_inicial
end
def ativa?
@ativa
end
end
def testar
begin
yield
rescue Exception => e
puts e
end
end
testar do
c = Conta.new true, 0
c.saldo = 1200
puts c.saldo
end
testar do
c = Conta.new true, 0
c.saldo = 0
puts c.saldo
end
testar do
c = Conta.new false, 0
c.saldo = 1200
puts c.saldo
end
Porém gostaria de criar uma invariante para o Objeto, algo que seja verificado quando qualquer operação seja executada,
teria um modo nativo no Ruby de se interceptar todos os métodos do Objeto e chamar um outro método ?
Grato a todos.