让我说我有这个对象:
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
在上面的示例中,如何有条件地分配关键字参数?
答案 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