我正在尝试实施javax.sql.rowset.serial.SerialBlob
。
让我们说custom attribute accessors with validation
。现在这个attr_validated
1:应该使用与attr_accessor相同的setter和getter方法。 ## 此部分已完成。
2:它应该验证给定的块。
attr_validated
这个问题可能看起来像任何其他问题,但事实并非如此。 谷歌搜索时我得到了
1: Ist Part
attr_validated :num_legs do |v|
v <= 4
end
2:我们如何实施第二部分。
任何帮助将不胜感激!!!
答案 0 :(得分:4)
这样的事情怎么样:
class Class
def attr_validated(*args, &validator)
args.each do |name|
define_method("#{name}=") do |value|
if block_given?
raise ArgumentError, "Value '#{value}' is invalid" unless validator.call(value)
end
instance_variable_set("@#{name}", value)
end
define_method(name) do
instance_variable_get("@#{name}")
end
end
end
end
class Person
attr_validated(:name, :occupation) { |name| name.length > 3 }
end
p1 = Person.new
p1.name = "John The Tester"
p1.occupation = "Software developer"
p "#{p1.name} - #{p1.occupation}"
p2 = Person.new
p2.name = "test"
p2.occupation = "Tester"
p "#{p2.name} - #{p2.occupation}"
哪个会产生如下输出:
"John The Tester - Software developer"
app.rb:6:in `block (2 levels) in attr_validated': Value 'test' is invalid (ArgumentError)
from app.rb:28:in `<main>'
希望有所帮助!
祝你好运!<强>更新强>
您可以添加另一个方法,对第一个参数应用验证,如下所示:
class Class
def attr_validated_first(*args, &validator)
args.each_with_index do |name, index|
define_method("#{name}=") do |value|
if block_given? && index == 0
raise ArgumentError, "Value '#{value}' is invalid" unless validator.call(value)
end
instance_variable_set("@#{name}", value)
end
define_method(name) do
instance_variable_get("@#{name}")
end
end
end
end
但是我不推荐这种方法,这会令人困惑!如果你想用不同的验证规则注册几个属性......你可以多次使用第一个例子中的attr_validated
,如下所示:
class Person
attr_validated(:name) { |name| name.length > 3 }
attr_validated(:occupation) { |occupation| occupation == "Ruby Developer" }
end
答案 1 :(得分:3)
这很容易。如果块表示参数无效,则只需raise
ArgumentError
设置器中的class Person
attr_reader :name
def name=(name)
raise ArgumentError, "'#{name}' is not a valid name!" if rejector.(name)
@name = name
end
private
attr_accessor :rejector
def initialize(&rejector)
self.rejector = rejector
end
end
artist = Person.new do |person|
person.length > 6
end
artist.name = 'The Artist Formerly Known As Prince'
# ArgumentError: 'The Artist Formerly Known As Prince' is not a valid name!
artist.name = 'ruby'
# => 'ruby'
:
MAX(If(subjects.name="Chemistry",marks.marks,'')) Chemistry,
MAX(If(subjects.name="Physics",marks.marks,'')) Physics,
.....