【问题标题】:Extending Enumerable in Rails 3在 Rails 3 中扩展 Enumerable
【发布时间】:2011-07-13 22:21:12
【问题描述】:

问题更新
这是我根据一些研究和发现所做的。

第 1 步 - 我的 Rails 3 项目中有这个模块,并将它放在我的 lib 文件夹中

# lib/enumerable.rb
module Enumerable
   def sum
      return self.inject(0){|acc,i|acc +i}
   end

   def average
      return self.sum/self.length.to_f
   end

   def sample_variance 
       avg=self.average
       sum=self.inject(0){|acc,i|acc +(i-avg)**2}
       return(1/self.length.to_f*sum)
   end

   def standard_deviation
       return Math.sqrt(self.sample_variance)
   end

end

第 2 步 - 根据blog article,在 Rails 3 中,您的 lib 文件夹不会自动加载。要加载此模块,您需要转到 config / application.rb 并输入:

config.autoload_paths += %W(#{config.root}/lib)

第 3 步 - 然后在你的模型中,我的理解是你输入这个来获取模块。

class MyModel < ActiveRecord::Base
    include Enumerable
end

第 4 步 - 然后我尝试重新启动 rails 服务器并尝试一下,当我认为它是真的时,我得到了错误。

MyModel.respond_to?('sample_variance')
# false, when it should be true

我做错了什么?我不应该说实话吗?

【问题讨论】:

标签: ruby ruby-on-rails-3 module enumerable


【解决方案1】:

如果我了解您的意思,您正在尝试在 ActiveRecord 中使用 Enumerable 的 sum 方法。您可以通过将当前对象转换为数组,然后在该数组上调用 Enumerable 的 sum 方法来做到这一点。

还有一件事:你不需要像使用它那样使用 return。 Ruby 会从你的方法返回最后计算的东西。你也不需要像这样使用 self —— 在 Ruby 中,self 是当前对象。

所以如果你有一个方法:

def charlie
  inject{|i, j| i + j + 1}
end

你这样称呼它:

(1..2).charlie

self 是当前对象(1..2)

输出将是4,没有自我或返回。

我强烈推荐 Dave Thomas 关于 Ruby 元编程的讲座,我试图找到它,但我找不到,它在网络上的某个地方。

【讨论】:

  • 好的,感谢关于 sum 和 self 的提示。但是我仍然想了解的是,如果我有一个想要添加到模型中的 module,我该怎么做才能在我的 Rails 3 项目中获取它。以及是否应该将其称为 Enumerable 或其他名称,因为它可能与命名空间冲突。
【解决方案2】:

你可能想看看这个:

http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html

您可以在一个类中包含一个模块,从而使该模块的方法对该类可用。

如果您将 Enumerable 包含到 Rails 模型中,那么它的方法将可用于该模型。但是由于 Enumerable 的方法已经可用于 Rails 项目中的某些类型的对象,并且这些对象可以从模型内部实例化,我不明白您为什么要这样做,因为 Enumerable 的方法对于它们的设计目的。

无论如何,您可能会发现以下其中一项可能适合您:

--使用Activerecord的sum方法

-- 将你的对象转换为数组,并使用 Enumerable 的 sum 方法

--编写自己的方法,但不要称其为sum,因为您不想混淆自己。

尝试在下面的 sn-p 中注释掉第二次出现的模块 Neuone,看看会发生什么。然后尝试注释掉 Charlie.one 方法,看看会发生什么。

module Neuone
def one
  'neuone one'
end 

def two
  'neuone two'
end

结束

module Neuone
def two
  'neuone two two'
end

结束

查理班 包括 Neuone

def one
    'charlie one'
end

结束

c = Charlie.new 个人电脑 p c.二

【讨论】:

  • 我自己很困惑。我试图用这个模块扩展当前的 Enumerable 类,但我显然没有掌握模块在 Ruby 中是如何工作的,以及我如何通过在模块中使用相似的方法名称来混淆自己(即 ActiveRecord - sum vs My Modules -sum) .谢谢你的例子,我会多读一点。
【解决方案3】:

您包含的主要 Enumerable 模块(不是您的扩展)无疑是有效的,您可以通过简单地检查任何混入的方法来测试它。问题是,您的“包含 Enumerable”可能没有包含您的文件,而是主模块。

一个建议是重命名扩展名的文件名,并通过带有

的初始化程序加载它
require 'my_enumerable.rb'

这样你肯定会同时加载 Enumerable 和你的 Enumerable 扩展。

【讨论】:

    猜你喜欢
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 2011-04-29
    • 1970-01-01
    相关资源
    最近更新 更多