Ruby-使用nil参数支持不同类型的类

Ruby-使用nil参数支持不同类型的类,ruby,Ruby,在Ruby中,假设我有一个名为Song的类。我想知道如何正确地编写初始化,以便它支持两种不同类型的。例如: song = Song.new(:cloud) #=> "CloudStorage class initialized" song.storage_kind #=> CloudStorage song.play #=> "...playing song" song\u full=song.new(来自SomeCloudStorage) song\u preview=so

在Ruby中,假设我有一个名为
Song
的类。我想知道如何正确地编写
初始化
,以便它支持两种不同类型的。例如:

song = Song.new(:cloud) #=> "CloudStorage class initialized"
song.storage_kind #=> CloudStorage
song.play #=> "...playing song"
song\u full=song.new(来自SomeCloudStorage)

song\u preview=song.new(来自本地存储)

然后说我有一个歌曲类,我总是想分配
@time\u stamp
,但是根据是否有
云存储
,分配
@cloud\u存储

def initialize(cloud_storage = nil, time_stamp = nil, local_storage = nil)
    @time_stamp = time_stamp || (Time.now.to_f * 1000).to_i.to_s
    @cloud_store_spec = cloud_storage
end 
我正在考虑使用
nil
,正如我所做的那样,但是代码会知道哪个是
cloud\u存储
,哪个是
local\u存储
。真的有可能吗


感谢您的帮助吗?

首先,使用关键字参数允许您将相关数据传递给初始值设定者(如果您希望将时间戳作为关键字或常规参数,则由您决定):

这将使调用类时更加清楚,允许:

song_full = Song.new(cloud_storage: fromSomeCloudStorage)
song_preview = Song.new(local_storage: fromLocalStorage)
就您的代码如何知道代码是来自云还是本地而言,如果您指的是类的实例,您只需检查是否存在
@cloud\u store\u spec
,例如:

def cloud_storage?
  @cloud_store_spec.present?
end
然后,您可以从代码中的任何其他位置调用:

song_full = Song.new(cloud_storage: fromSomeCloudStorage)
song_full.cloud_storage? # => true

song_preview = Song.new(local_storage: fromLocalStorage)
song_preview.cloud_storage? # => false
希望这能帮上忙,我对你的理解是正确的:)让我知道你进展如何,或者如果你有任何问题


Ruby 1.9.3的更新

由于Ruby 2.0中引入了关键字参数,因此对于1.9.3,您可以使用选项哈希:

def initialize(options = {}) # again, timestamp can be a separate arg if you'd prefer
  @time_stamp = options[:time_stamp] || (Time.now.to_f * 1000).to_i.to_s
  @cloud_store_spec = options[:cloud_storage]
end

代码的其余部分将保持不变。

如果可以将CloudStorage或LocalStorage视为类:

class LocalStorage
  def initialize; p 'LocalStorage class initialized'; end
end

class CloudStorage
  def initialize; p 'CloudStorage class initialized'; end
  def play; p "...playing song"; end
end

也许你可以考虑硬编码一个哈希,(让时间戳分开):< /P> 例如,您可以调用:

song = Song.new(:cloud) #=> "CloudStorage class initialized"
song.storage_kind #=> CloudStorage
song.play #=> "...playing song"

Sweet-太好了,我从来都不知道分号参数注释。我实际上也在使用一个旧版本的Ruby 1.9.3——假设它在那里受支持。太好了,很高兴它有帮助!关键字args是在2.0 IIRC中引入的-给我两分钟,我会用你在1.9.3中可以使用的方法更新答案:)在更新@userMod2中弹出。让我知道这一切是否都对您有效,如果是的话,请随时接受答案。啊,因此即使在执行
def initialize(options={})
时,我仍然可以执行
song\u preview=song.new(local\u storage:fromLocalStorage)
是的-您可以提供一个未包装的哈希作为Ruby中任何方法调用的最终参数,这意味着上面的内容等同于
Song.new({local\u storage:fromLocalStorage})
。如果您提供了附加参数,则同样适用-无需包装它们。
initialize(storage,time_stamp=nil)
如何使用
storage
作为
LocalStorage
CloudStorage
的实例,每个实例都是泛型
storage
类的子类?这样,
Song
只需知道如何使用
存储
,子类就可以完成实际工作。
song = Song.new(:cloud) #=> "CloudStorage class initialized"
song.storage_kind #=> CloudStorage
song.play #=> "...playing song"