在Rails中扩展可枚举3

时间:2011-03-12 04:51:27

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

更新问题
以下是我根据一些研究和调查结果所做的工作。

第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

我做错了什么?我不应该成真吗?

3 个答案:

答案 0 :(得分:2)

您包含的主要Enumerable模块(不是您的扩展程序)无疑是有效的,您只需检查混合的任何方法即可对其进行测试。问题是,您的“包括可枚举”可能未包含您的文件,而是主要模块。

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

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

这样你肯定会同时获得Enumerable和扩展到Enumerable。

答案 1 :(得分:0)

如果我理解你正在驾驶的是什么,那么你试图在ActiveRecord中使用Enumerable的sum方法。你可以通过将当前对象转换为数组,然后在该数组上调用Enumerable的sum方法来实现。

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

所以,如果你有一个方法:

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

你这样称呼它:

(1..2).charlie

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

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

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

答案 2 :(得分:0)

你可能想看看这个:

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

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

如果将Enumerable包含在Rails模型中,则其模型可以使用其方法。但是由于Enumerable的方法已经可用于Rails项目中的某些类型的对象,并且这些对象可以从模型中实例化,我不明白为什么你可以这样做,因为Enumerable的方法对于目的是他们的设计。

无论如何,您可能会发现以下其中一项可能对您有用:

- 使用Activerecord的求和方法

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

- 编写自己的方法,但不要称之为总和,因为你不想让自己迷惑。

尝试在下面的代码段中注释掉第二次出现的模块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.one p c.two