Ruby 方法调用中是否有记忆约定?

Ruby 方法调用中是否有记忆约定?,ruby,coding-style,memoization,Ruby,Coding Style,Memoization,我希望避免在方法调用中重新评估值。直到现在,我一直在这样做: def some_method @some_method ||= begin # lot's of code end end 但结果很难看。在一些代码中,我看到如下内容: def some_method @some_method ||= some_method! end private def some_method! # lot's of code end 我不喜欢结尾的砰砰声(!),所以我想到了这个

我希望避免在方法调用中重新评估值。直到现在,我一直在这样做:

def some_method
  @some_method ||= begin
    # lot's of code
  end
end
但结果很难看。在一些代码中,我看到如下内容:

def some_method
  @some_method ||= some_method!
end

private

def some_method!
  # lot's of code
end
我不喜欢结尾的砰砰声(
),所以我想到了这个:

def some_method
  @some_method ||= _some_method
end

private

def _some_method
  # lot's of code
end
  • 在前面加下划线是一个好习惯吗
  • 对于记忆化/非记忆化的方法对是否有其他约定
  • 是否有一些惯例来记忆多行方法

    • 我会这样做:

      def filesize
        @filesize ||= calculate_filesize
      end
      
      private
      
      def calculate_filesize
        # ...
      end
      

      因此,我会用不同的方法命名,因为我认为它更有意义。

      我通常使用第一个示例中的
      begin,end
      ,但是如果有更多的代码,我只看变量是否存在,不需要为此创建另一个方法

      def some_method
        return @some_method if @some_method
        # lot's of code
        @some_method
      end
      

      我认为还有一种方式,更具Java风格

      首先,您应该实现注释,如“”和“”

      然后,您应该添加类似于_cacheable的注释,该注释将告诉方法它应该返回实例变量,如果它为null,则应该通过调用方法来计算它,这样您的代码将更加清晰:

      _cacheable
      def some_method
         # do_some_work
      end
      

      我也不喜欢爆炸。我用

      def some_method 
        @some_method_memo ||= some_method_eval 
      end 
      
      private 
      
      def some_method_eval
        # lot's of code 
      end 
      
      这里的
      eval
      评估的缩写。我喜欢它的阅读方式,也喜欢它使公共界面简洁

      我鄙视依赖下划线作为区分标记的约定:它们都容易出错,并且要求我记住YAMC(另一个毫无意义的约定)。Ada语言是为安全关键应用程序设计的,不允许使用前导、尾随或多个下划线。好主意。

      我通常会这样回答或:

      def filesize() @filesize ||=
        calculate_filesize
      end
      
      顺便说一句:

      我经常使用这种记忆技巧:

      def filesize() @_memo[:filesize] ||=
        calculate_filesize
      end
      
      这将允许您稍后用一个简单的
      @\u memo.clear
      清除所有已记忆的变量。@|u memo变量的初始化应如下所示
      Hash.new{h,k|h[k]=Hash.new}
      。 它为您提供了使用ActiveSupport::Memoize和类似的元编程技术的许多优点。

      我使用gem,它让您可以轻松地记忆一个方法,而无需更改原始方法或创建两个方法

      例如,与其使用两种方法,
      file\u size
      calculate\u file\u size
      ,还不如自己使用一个实例变量来实现记忆:

      def file_size
        @file_size ||= calculate_file_size
      end
      
      def calculate_file_size
        # code to calculate the file size
      end
      
      您可以这样做:

      def file_size
        # code to calculate the file size
      end
      memoize :file_size
      
      每个已记忆的函数都有一种刷新现有值的方法

      object.file_size       # returns the memoized value
      object.file_size(true) # bypasses the memoized value and rememoizes it
      

      因此,调用
      object.file\u size(true)
      将等同于调用
      object.calculate\u file\u size

      ,这是行不通的。您需要将
      return
      放在def的第一行前面。我唯一不喜欢这种方法的是,编码人员需要编辑方法,以便将
      @some_method
      变量分配到其中的某个位置,从而在方法的逻辑中混合了记忆逻辑。我认为您太苛刻了,因为这首先取决于方法的作用。例如,我有时在rails助手中使用它,这非常有意义。更不用说模块内部的private关键字一开始就不能很好地工作。另外,由于你也对AGI投了否决票,所以仅仅因为你不完全同意他们就对所有答案投否决票是不好的。相关:使用Rails的class
      ActiveSupport::Memoize
      似乎很好:。你希望得到什么样的答案?Vise和Agis都提出了良好的约定。另外,您的第二块代码是一个常见的约定。我喜欢
      | |=begin…end
      。我觉得很优雅,由你决定__一些方法,计算一些方法,计算一些方法,计算一些方法,一些方法,一些方法,一些方法代码注意:在什么时候和为什么要使用感叹号。我认为这有点超出了公约的目的,但值得考虑。再次稍微偏离了这里的相关内容,但有价值,所以尽管说“我没有修改对象”是可以的,但说“我不喜欢爆炸”是避免它的一个不太明显的理由。我不喜欢在方法名称前放这么多字符,以便将其标记为未经修改的版本。为什么?它在语义上是有意义的,并且非常明显它在做什么。对更少角色的盲目追求让你忽略了最佳答案。+1。这些名称准确地描述了函数正在做的事情,包括它们的预期性能。尽管赏金去了其他地方,但我还是接受这个名称,因为它更符合其他ruby约定。请投票支持最后的(积极的)长篇大论。烧掉所有YAMC:)