首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Ruby中用不同的参数和默认值初始化Class最有效的方法是什么?

在Ruby中用不同的参数和默认值初始化Class最有效的方法是什么?
EN

Stack Overflow用户
提问于 2010-12-29 21:02:55
回答 6查看 40.3K关注 0票数 30

我希望有一个类和一些属性,您可以在初始化期间设置它们,也可以使用它的默认值。

代码语言:javascript
复制
class Fruit
  attr_accessor :color, :type
  def initialize(color, type)
    @color=color ||= 'green'
    @type=type ||='pear'
  end
end

apple=Fruit.new(red, apple)
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-12-29 21:13:51

解决此问题的典型方法是使用具有默认值的散列。如果散列是方法的最后一个参数,Ruby有一个很好的语法来传递散列值。

代码语言:javascript
复制
class Fruit
  attr_accessor :color, :type

  def initialize(params = {})
    @color = params.fetch(:color, 'green')
    @type = params.fetch(:type, 'pear')
  end

  def to_s
    "#{color} #{type}"
  end
end

puts(Fruit.new)                                    # prints: green pear
puts(Fruit.new(:color => 'red', :type => 'grape')) # prints: red grape
puts(Fruit.new(:type => 'pomegranate')) # prints: green pomegranate

这里有一个很好的概述:http://deepfall.blogspot.com/2008/08/named-parameters-in-ruby.html

票数 66
EN

Stack Overflow用户

发布于 2010-12-30 04:12:42

Brian的回答很好,但我想建议一些修改,使其主要是meta:

代码语言:javascript
复制
class Fruit

  # Now this is the only thing you have to touch when adding defaults or properties
  def set_defaults
    @color ||= 'green'
    @type  ||= 'pear'
  end

  def initialize(params = {})
    params.each { |key,value| instance_variable_set("@#{key}", value) }
    set_defaults
    instance_variables.each {|var| self.class.send(:attr_accessor, var.to_s.delete('@'))}
  end

  def to_s
    instance_variables.inject("") {|vars, var| vars += "#{var}: #{instance_variable_get(var)}; "}
  end

end

puts Fruit.new
puts Fruit.new :color => 'red', :type => 'grape'  
puts Fruit.new :type => 'pomegranate'
puts Fruit.new :cost => 20.21
puts Fruit.new :foo => "bar"


f = Fruit.new :potato => "salad"
puts "f.cost.nil? #{f.cost.nil?}"

以下哪项输出:

代码语言:javascript
复制
@color: green; @type: pear; 
@color: red; @type: grape; 
@color: green; @type: pomegranate; 
@color: green; @type: pear; @cost: 20.21; 
@color: green; @type: pear; @foo: bar; 
f.cost.nil? true

当然,这并不是万能的完美解决方案,但它为您提供了一些使代码更具动态性的想法。

票数 11
EN

Stack Overflow用户

发布于 2010-12-29 21:32:14

我会这样做:

代码语言:javascript
复制
class Fruit
  attr_accessor :color, :type

  def initialize(args={})
    options = {:color => 'green', :type => 'pear'}.merge(args)

    self.color = options[:color]
    self.type  = options[:type]
  end
end

apple = Fruit.new(:color => 'red', :type => 'apple')

这样,您就不必担心缺少参数--或者它们的顺序--并且您将始终保留您的默认值。当然,如果默认值存在,.merge将覆盖默认值。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4554325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档