假设我有一个名为Task的类。
class Task
attr_accessor :task_name, :start, :end
def initialize(*args)
length = args.length
case length
when 0
puts "Task Created."
when 1
@task_name = args[0]
puts "Task Created."
when 3
@task_name = args[0]
@start = args[1]
@end = args[2]
puts "Task Created."
else
puts "Incorrect input"
end
end
end
我想问一些有关此实施的问题:
答案 0 :(得分:1)
不要使用" new",使用另一种调用" new"如果参数有效
class Task
attr_accessor :task_name, :start, :end
def initialize(*args)
@task_name = args[0]
@start = args[1]
@end = args[2]
puts "Task Created."
end
def self.fabricate(*args)
if [0, 1, 3].include?(args.length)
return new(*args)
else
puts "incorrect input"
return nil
end
end
end
result = Task.fabricate("job", 5, 7)
答案 1 :(得分:1)
您可以通过引发错误来阻止对象的创建,最常见的是ArgumentError
。当参数写在方法签名中时我喜欢它,所以我会这样做:
def initialize(task_name = nil, start = nil, end = nil)
unless [start, end].all?(&:nil?) || [start, end].none?(&:nil?)
raise ArgumentError, 'provide both start and end or none'
end
@task_name = task_name
@start = start
@end = end
end
很酷的是,当您传递给许多参数时,您可以免费获得ArgumentError
。 if条件也可以写得更短,因为它基本上是XOR
。不过我认为这是不太可以理解的:
def initialize(task_name = nil, start = nil, end = nil)
if start.nil? != end.nil?
raise ArgumentError, 'provide both start and end or none'
end
@task_name = task_name
@start = start
@end = end
end
答案 2 :(得分:1)
要回答您的问题,您需要了解new
方法的工作原理。如果它是用ruby编写的,它看起来像这样:
class Class
def self.new(args*)
object = allocate
object.initialize(*args)
object
end
end
allocate
方法负责在ruby的内存堆slab中创建一个新对象。分配对象时,将对此对象执行initialize
方法,并返回对象本身。
那么如何防止新对象被退回? - 在initialize
中提出异常!
您可以通过以下方式完成:
class Task
attr_accessor :task_name, :start, :end
def initialize(*args)
raise ArgumentError, "wrong number of arguments (#{args.length} for 0,1 or 3" unless [0,1,3].include?(args.length)
@task_name, @start, @end = args
end
end