Dies ist ein Weg, um den Code zu schreiben, die nicht Gebrauch von Alias-Namen machen. Es enthält eine Klassenmethode validate
, die die Validator-Methode und die Methoden angibt, die die Validator-Methode aufrufen sollen. Diese Methode validate
kann mehrmals aufgerufen werden, um den Validator zu ändern und dynamisch zu validieren.
class ActiveClass
end
Legen Sie alle andere Methoden als die Prüfungen in einer Unterklasse von ActiveClass
genannt (sagen wir) MidClass
.
class MidClass < ActiveClass
def do_this_method(v,a,b)
puts "this: v=#{v}, a=#{a}, b=#{b}"
end
def do_that_method(v,a,b)
puts "that: v=#{v}, a=#{a}, b=#{b}"
end
def yet_another_method(v,a,b)
puts "yet_another: v=#{v}, a=#{a}, b=#{b}"
end
end
MidClass.instance_methods(false)
#=> [:do_this_method, :do_that_method, :yet_another_method]
Legen Sie die Validierer, zusammen mit einer Klassenmethode validate
, in einer Unterklasse von MidClass
genannt (sagen wir) SubClass
.
class SubClass < MidClass
def self.validate(validator, *validatees)
superclass.instance_methods(false).each do |m|
if validatees.include?(m)
define_method(m) do |v, *args|
send(validator, v)
super(v, *args)
end
else
define_method(m) do |v, *args|
super(v, *args)
end
end
end
end
private
def validator1(v)
puts "valid1, v=#{v}"
end
def validator2(v)
puts "valid2, v=#{v}"
end
end
SubClass.methods(false)
#=> [:validate]
SubClass.private_instance_methods(false)
#=> [:validator1, :validator2]
die Klassenmethode validate
Symbole für die Validierungsmethode gelangt zu verwenden und das Verfahren zu validieren. Lass es uns versuchen.
sc = SubClass.new
SubClass.validate(:validator1, :do_this_method, :do_that_method)
sc.do_this_method(1,2,3)
# valid1, v=1
# this: v=1, a=2, b=3
sc.do_that_method(1,2,3)
# valid1, v=1
# that: v=1, a=2, b=3
sc.yet_another_method(1,2,3)
# yet_another: v=1, a=2, b=3
Jetzt die Validierung ändern.
SubClass.validate(:validator2, :do_that_method, :yet_another_method)
sc.do_this_method(1,2,3)
# this: v=1, a=2, b=3
sc.do_that_method(1,2,3)
# valid2, v=1
# that: v=1, a=2, b=3
sc.yet_another_method(1,2,3)
# valid2, v=1
# yet_another: v=1, a=2, b=3
Wenn super
ohne Argumente aus einer normalen Methode aufgerufen wird, alle Argumente und ein Block, wenn es einen gibt, sind super geführt. Wenn die Methode mit define_method
erstellt wurde, werden jedoch keine Argumente (und kein Block) an super übergeben. Im letzteren Fall müssen die Argumente explizit sein.
Ich wollte einen Block oder Proc auf super
übergeben, wenn es einen gibt, aber die falsche geheime Soße verwendet haben. Ich würde einen Rat begrüßen, um das zu tun.
Möchten Sie 'first_validate_something' aufgerufen haben, bevor * any * Methode aufgerufen wird (auch, sagen wir, to_s')? Wenn nicht, wie soll es entscheiden, welche Methoden "haken"? –
first_validate ist nur vor den Methoden als Argumente aufgeführt, so genannt, in diesem Fall #do_this_method und #do_that Methode Dies ist, was die Methodendefinition wie von SteveTurczyn zu stehlen aussehen: before_operations (before_method, * Methoden) Does Das beantwortet deine Frage? – Trajanson
Ja, tut es. Ich entschuldige mich, ich bin mobil und scrollte nicht weit genug, um das zweite und dritte Argument zu sehen! –