带有参数hash的Ruby方法,默认值为:如何干?

时间:2011-05-09 00:22:29

标签: ruby-on-rails ruby hash

我有一个initialize方法接受哈希来设置一些实例变量。这基本上就是我要做的事情:

class Ad
  DEFAULT_PAGE = 'index'.freeze

  DEFAULT_CHANNEL = 'general'.freeze

  DEFAULT_AREA = 'general'.freeze

  attr_accessor :page, :area, :channel

  def initialize args={}
    @page = args[:page] || DEFAULT_PAGE
    @area = args[:area] || DEFAULT_AREA
    @channel = args[:channel] || DEFAULT_CHANNEL
  end

  # ...
end

我看到了一个允许动态设置实例变量的提示,但我不确定如何也包含默认值......

  def initialize args={}
    args.each do |attr,val|
      instance_variable_set("@#{attr}", val) unless val.nil?
    end
  end

我可以动态引用一个常量吗?或者欢迎任何更好的做这种事情的方式!

...我也意识到attr_accessor变量可以单独设置。但我只是想这样做。 :)

2 个答案:

答案 0 :(得分:9)

如果实例变量位于defaults哈希中,那么它也只会创建实例变量,这样就不会意外地创建/覆盖其他实例变量。

我假设你想说unless val.nil?

def initialize(args={})
  defaults = {
    :page    => DEFAULT_PAGE,
    :area    => DEFAULT_AREA,
    :channel => DEFAULT_CHANNEL
  }.merge(args).each do |attr, val|
    instance_variable_set("@#{attr}", val) if defaults.has_key?(attr) && (not val.nil?)
  end if args
end

答案 1 :(得分:1)

试试这个:

  def initialize args={}
    defaults = {
      :page    => DEFAULT_AREA, 
      :area    => DEFAULT_AREA, 
      :channel => DEFAULT_CHANNEL
    }
    args.reverse_merge(defaults).each do |attr,val|
      instance_variable_set("@#{attr}", val) unless val.nil?
    end
  end