【问题标题】:Reusing code ruby on rails在 Rails 上重用代码 Ruby
【发布时间】:2013-03-14 13:51:53
【问题描述】:

我的项目中有一个模块位于 lib/.它的内容是这样的:

module Search
  module Score

    def get_score
      return 'something'
    end

  end    
end

此搜索有许多不同的模块,我需要使用 Score。我意识到我需要在我的模型中添加 require (我正在尝试从模型中使用它)。所以这是我的代码(模型):

require 'search'

class User < ActiveRecord::Base

  def get_user_score
    #tried this :
    p Search::Score.get_score #error
    #this as well
    score_instance = Score.new #error
    score = Search::Score.get_score # error undefined method `get_score'
  end

end

那么如何重用我在其他类(模块)中的代码?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    要使其正常工作,您可以将模块混合到您的类中:

    require 'search'
    
    class User < ActiveRecord::Base
      include Search::Score
    
      def get_user_score
        p get_score # => "something"
      end
    end
    

    或者你可以在你的模块中定义类似于类方法的方法:

    module Search
      module Score
        def self.get_score
          return 'something'
        end
      end    
    end
    

    如果你这样做,你可以像预期的那样调用get_score

    require 'search'
    
    class User < ActiveRecord::Base
      def get_user_score
        p Search::Score.get_score # => "something"
      end
    end
    

    请参阅this tutorial,了解有关 Ruby 中模块的更深入解释。

    【讨论】:

      【解决方案2】:

      首先,请参阅“Best Practices for reusing code between controllers in Ruby on Rails”。

      关于将代码重用为模块,请查看“Rethinking code reuse with Modularity for Ruby”。

      【讨论】:

        【解决方案3】:

        “模块是残缺的类”

        模块就像 Ruby 中的残缺类。如果您查看继承链,您会发现 Class 实际上继承自 Module。

        模块无法实例化。所以对 .new 的调用不起作用。

        但是,您可以做的是将您的方法指定为“类”方法(我知道我说过它不是类...)

        所以你可以像这样在前面添加一个自我:

        module Search
          module Score
        
            def self.get_score
              return 'something'
            end
        
          end    
        end
        

        然后您可以像在代码示例中尝试的那样将此方法作为类方法调用

        【讨论】:

        • 我不会称他们为残废班级。它们是一个非常强大的特性,有充分的理由存在,并且是使 Ruby 成为一种很酷的语言的关键。 Comparable 和 Enumerable 是强大的模块,它们展示了模块的优点。
        【解决方案4】:

        Search::Score 是一个模块而不是一个类,所以Score.new 将不起作用。

        您可以尝试将get_score函数的签名更改为self.get_score

        【讨论】:

          【解决方案5】:

          以上回答中除了def self.get_score,还有extend self,像这样:

          module Search
            module Score
              extend self
          
              def get_score
                return 'something'
              end
            end    
          end
          

          module_function:

          module Search
            module Score
              module_function
          
              def get_score
                return 'something'
              end
            end    
          end
          

          后者实际上是 RuboCop (source) 中的首选方法,尽管在实践中我个人并不经常看到它。

          【讨论】:

            猜你喜欢
            • 2010-10-20
            • 2015-10-08
            • 1970-01-01
            • 2021-04-09
            • 1970-01-01
            • 1970-01-01
            • 2011-07-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多