Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在初始化时使用attr_访问器设置ruby 2.0关键字参数_Ruby - Fatal编程技术网

在初始化时使用attr_访问器设置ruby 2.0关键字参数

在初始化时使用attr_访问器设置ruby 2.0关键字参数,ruby,Ruby,我如何在不必全部编写相同代码的情况下动态设置 现在代码如下所示: def initialize(keywords: keywords, title: title, url: url, adsetting: adsetting) self.keywords = keywords self.title = title self.url = url self.adsetting = adsetting end 如果列表变长,很快就会失控 对于ruby 1.9,我只需向该方法传递一个哈

我如何在不必全部编写相同代码的情况下动态设置

现在代码如下所示:

def initialize(keywords: keywords, title: title, url: url, adsetting: adsetting)
  self.keywords = keywords
  self.title = title
  self.url = url
  self.adsetting = adsetting
end
如果列表变长,很快就会失控

对于ruby 1.9,我只需向该方法传递一个哈希。像这样:

def initialize(args)
  args.each do |k,v|
    instance_variable_set("@#{k}", v) unless v.nil?
  end
end
但我宁愿使用Ruby 2.0关键字参数。可以实现类似的目标吗?

def initialize(keywords: keywords, title: title, url: url, adsetting: adsetting)
  args.each do |k,v|
    instance_variable_set("@#{k}", v) unless v.nil?
  end
end

或者按照约翰·莱德贝特和卡里·斯沃夫兰的建议:

def initialize(keywords: nil, title: nil, url: nil, adsetting: nil)
  method(__method__).parameters.each do |type, k|
    next unless type == :key
    v = eval(k.to_s)
    instance_variable_set("@#{k}", v) unless v.nil?
  end
end

下面是一个基于Sawa答案的工作示例。选项编号#1与继承不匹配

class CsvOutline
  def initialize( headers: [],
                  body: [],
                  folder: 'tmp',
                  file_prefix: 'test',
                  filename: "#{file_prefix}_#{Time.zone.now.strftime("%Y%m%d%H%M%S")}.csv",
                  path: File.join(folder, filename))
    # Set instance variables and attribute accessors based on named parameters in initialize
    local_variables.each do |k|
      class_eval do
        attr_accessor k
      end
      v = eval(k.to_s)
      instance_variable_set("@#{k}", v) unless v.nil?
    end
  end
end
现在如果我要创建一个子类

class ReportCsv < CsvOutline
  def initialize
     super(folder: 'reports', file_prefix: 'Report')
  end
end 
class ReportCsv

现在,子项将使用正确的文件夹和文件前缀进行初始化。如果我要使用第二个选项-它们将被初始化为nIL.

如果您使用的是V2.5或以上的Ruby,请考虑使用<代码>结构> <代码>:

MyClass=Struct.new(:foo,:bar,关键字_init:true)
MyClass.new(foo:1,bar:2)

不错。不知道存在局部变量。您还可以查看
self.method(:initialize).parameters
,它还将告诉您参数的类型(例如可选、必需、键、全局…)@johnledbooter实际上,这可能比我的答案更好。@johnledbooter!可以使用
\uuuu方法\uuuu
代替
初始化
。John Ledbetter和Cary Swoveland的建议对继承不太有效。如果我是从一个初始化了第二个方法的类继承的-如果我试图传递任何东西,我会得到子类的zilch。适用于局部变量-我实际上尝试了两者-请参见下面的答案
class ReportCsv < CsvOutline
  def initialize
     super(folder: 'reports', file_prefix: 'Report')
  end
end