是否可以在某些指定方法之前调用before_action
,例如在rails中?
class Calculator
before_action { raise Exception, "calculator is empty" if @numbers.nil? },
only: [:plus, :minus, :divide, :times]
def push number
@numbers ||= []
@numbers << number
end
def plus
# ...
end
def minus
# ...
end
def divide
# ...
end
def times
# ...
end
# ...
end
答案 0 :(得分:6)
可以用纯红宝石来完成!一种方法是使用method aliasing
class Foo
def bar
#true bar
end
alias_method :original_bar, :bar
def bar
before_stuff
original_bar
after_stuff
end
end
但是对于更通用的方法,您可以阅读this thread
您的代码的示例可以是:
class Calculator
def plus
...
end
def end
...
end
def divide
...
end
den times
...
end
[:plus, :minus, :divide, :times].each do |m|
alias_method "original_#{m.to_s}".to_sym, m
define_method m do
check_numbers
send("original_#{m.to_s}".to_sym)
end
end
private
def check_numbers
raise Exception, "calculator is empty" if @numbers.nil?
end
end
答案 1 :(得分:3)
您正在寻找的是Aspect oriented programming对红宝石的支持。有几个宝石实现了这一点,比如aquarium。
我认为,在你的情况下,一些懒惰的检查就足够了:
class Calculator
def numbers
raise Exception, "calculator is empty" if @numbers.nil?
@numbers
end
def push number
@numbers ||= []
@numbers << number
end
def plus
numbers.inject(:+) # <-- will throw the correct Exception if `@numbers` is nil
# ...
end
def minus
# ...
end
def divide
# ...
end
def times
# ...
end
# ...
end
答案 2 :(得分:1)
您可以添加active_support
中的ActiveSupport::Callbacks并定义您需要的任何回调:
文档中的示例:
class Record
include ActiveSupport::Callbacks
define_callbacks :save
def save
run_callbacks :save do
puts "- save"
end
end
end
class PersonRecord < Record
set_callback :save, :before, :saving_message
def saving_message
puts "saving..."
end
set_callback :save, :after do |object|
puts "saved"
end
end
person = PersonRecord.new
person.save
# Output:
# saving...
# - save
# saved
答案 3 :(得分:0)
你可以编写自己的逻辑,所以它是可能的。但在这种情况下,我认为你不需要。 Ruby为您提供了一个处理它的工具。您可以使用类initialize
方法,该方法在首次初始化类时调用:例如,Calculate.new
class Calculator
def initialize(inputs)
raise Exception, "calculator is empty" unless inputs
end
# ... rest of the class
end
您需要输入任何数学运算,为什么不添加init方法?如果没有传入数字,那么很难做任何数学运算。
小心将Rails控制器逻辑移植到纯Ruby。 Rails控制器本身不是典型的OOP,它们违反了许多OOP规则。 Ruby更灵活。