条件关键字参数(Ruby 2.0)

时间:2013-11-27 02:43:40

标签: ruby

让我说我有这个对象:

class Post
  def initialize(title: 'title', content: 'content')
    @title = title
    @content = content
  end
end

但我想添加如下逻辑:

class Post
  def initialize(title: 'title', content: 'content')
    @title = title unless title.empty? # if it's empty I'd like to use the default value
    @content = content unless content.empty?
  end
end

在上面的示例中,如何有条件地分配关键字参数?

2 个答案:

答案 0 :(得分:2)

使用更好的答案重新审视这一点......这正是fetch用于:

class Post
  def initialize(options)
    @title = options.fetch(:title, 'title')
    @content = options.fetch(:content, 'content')
  end
end

以下是如何使用此逻辑:

irb(main):007:0> post = Post.new(title: 'A Very Short Story', content: 'Hello World!')
=> #<Post:0x00007fadc6829878 @title="A Very Short Story", @content="Hello World!">
irb(main):008:0> post = Post.new(title: 'A Nonexistent Story')
=> #<Post:0x00007fadc6820138 @title="A Nonexistent Story", @content="content">  # Notice how 'content' was set using the default option

旧(有效但使用更多代码)答案

为什么不在单独的方法中设置默认值,然后在初始化时传递的参数中合并?如果没有传递参数,那么默认值就会启动。否则,默认值会被初始化时传入的参数覆盖。

例如:

class Post
  def initialize(options)
    options = defaults.merge(options)
    @title   = options[:title]
    @content = options[:content]
  end

## Code omitted ##

  private def defaults
    {
      title:  "Your Default Title"
      content: "Your Default Content"
    }
  end
    ...
end

答案 1 :(得分:1)

我觉得这里有代码味道。您试图在两个独立条件下为变量分配默认值:未给出参数时,以及参数为空时。那不是一个好的设计。它是导致错误的潜在原因,并且使维护变得困难。我建议你应该采取以下两种方式之一:

(i)使参数成为可能的(即,传递nil或空值而不是传递参数),并在方法体中进行验证:

class Post
  def initialize(title, content)
    @title = title.nil? || title.empty? ? "title" : title
    @content = content.nil? || content.empty? ? "content" : content
  end
end

(ii)不要传递空值作为参数,不要传递它:

class Post
  def initialize(title: "title", content: "content")
    @title, @content = title, content
  end
end