ruby-on-rails - 用任意名称定义方法

标签 ruby-on-rails ruby

我的 Rails 应用程序有一个名为 GameActiveRecord 模型,它存储和关联有关体育比赛的信息,包括 home_team_idhome_team_score 以及 winning_team_idwinning_team_score 等方法,它们将逻辑应用于存储的数据。

我在 app/models/ 中有另一个文件,它定义了一个独立的类 Recordrecord 是通过将 games 数组和 team_id 作为参数传递来创建实例变量的,例如 @wins@points_for 对应于 team_idteam

Record 中,我定义了两个实例方法 average_points_foraverage_points_against,它们完全符合您的预期:

class Record
    def games_played
        return @wins + @losses
    end
    def average_points_for
        return (@points_for.to_f / games_played).round(2)
    end
    def average_points_against
        return (@points_against.to_f / games_played).round(2)
    end
end

似乎非 DRY 将 average_points_foraverage_points_against 声明为两种不同的方法。我意识到我可以做到这一点......

class Record
    def games_played
        return @wins + @losses
    end
    def average_points(which)
        return eval("(@points_#{which}.to_f / games_played).round(2)")
    end
end

...但是 average_points("for") 看起来很丑 — 我更喜欢 average_points_for 的约定。

我更喜欢这样的东西:

class Record
    def games_played
        return @wins + @losses
    end
    def average_points_#{which}
        return (@points_#{which}.to_f / games_played).round(2)
    end
end

有办法吗?

最佳答案

在我看来,对于您的用例,将其重构为 DRY it 会更干净:

private def average(value)
  (value.to_f / games_played).round(2)
end

def average_points_for
  average(@points_for)
end

def average_points_against
  average(@points_against)
end

但是,如注释所示,您可以使用 define_method。 Rails 这样做有很大的好处,就像 Ruby 本身在 OpenStruct 中一样;但在这种情况下这是一种矫枉过正。如果你真的想这样做,这就是方式(未经测试,可能包含错误):

%i(for against).each do |which|
  define_method(:"average_points_#{which}") do
    (instance_variable_get(:"@points_#{which}").to_f / games_played).round(2)
  end
end

关于ruby-on-rails - 用任意名称定义方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42990138/

相关文章:

ruby - 如何升级rubygems

ruby-on-rails - 无法删除文件

ruby - ruby 中流的 AES CBC 加密?

javascript - rails : rendering html and js in one request

ruby-on-rails - Rails 链接到当前页面并向其传递参数

ruby-on-rails - 无法安装回形针 rails 3.0.7

jquery - Bootstrap 轮播不工作

mysql - 从 CSV 批量更新 MySQL 数据库

ruby-on-rails - Elastic Beanstalk 间歇性激活机架 1.5.2,但我的 Gemfile 需要机架 1.6.0

ruby - 在 puppet 中添加自定义函数