是否可以在Ruby中执行before_action(如在Rails中)?

是否可以在某些指定的方法之前调用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 

您正在寻找的是针对ruby的面向方面编程支持。 有几个gem实现这一点,如水族馆 。

我认为,在你的情况下,一些懒惰的检查就足够了:

 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 

它可以用纯ruby来完成! 一种方法是使用方法别名

 class Foo def bar #true bar end alias_method :original_bar, :bar def bar before_stuff original_bar after_stuff end end 

但是对于更通用的方法,你可以阅读这个post

您的代码的示例可以是:

 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 

你可以写自己的逻辑,所以它是可能的。 但在这种情况下,我认为你不需要。 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更灵活。

您可以在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