ruby:大量初始化实例变量 [英] ruby: mass initializing instance variables

查看:181
本文介绍了ruby:大量初始化实例变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个简单的方法来批量分配实例变量

  def initialize(title:nil,label_left:nil,label_right: nil,color_set:nil)
@title = title
@label_left = label_left
@label_right = label_right
@color_set = color_set
end
>解决方案

如果你想要特定的变量,那么不是真的。在这里使用反射,即使它是可用的,也会有麻烦。



你在这里得到的是最微不足道的情况。通常你会看到看起来更像这样的代码:

  def initialize(title:nil,label:nil,label_width:nil ,color_set:nil)
@title = title.to_s
@label = label_left.to_s
@label_width = label_width.to_i
@color_set = MyRGBConverter.to_rgb(color_set)
end

初始化程序是一个可以进行必要的转换和验证的地方。如果这些参数中的一些需要是一定的值,你将测试, raise 一个错误上的异常等等。



这会导致这样的代码:

  def initialize(title:nil,label:nil,label_width:nil,color_set:nil)
@title = title.to_s
unless(@ title.match(/ \S /))
raise未指定标题
end

@label = label_left.to_s
除非(@ label.match(/ \A\w + \z /))
raise无效标签#{@label.inspect}
end

@ label_width = label_width.to_i
if(@label_width< = 0)
raise标签宽度必须大于0,指定#{@ label_width}。
end

@color_set = MyRGBConverter.to_rgb(color_set)
end


b $ b

如果你真的不在乎你接受哪个参数,那么你可以在Ruby 2.3中使用新的 keyword-arguments 说明符 * *

  def initialize(** options)
options.each do | key ,value |
instance_variable_set(@#{key},value)
end
end

请注意,如果这些值是用户提供的,那么可能会有潜在危险,因此您可能希望以某种方式将它们列入白名单:

  VALID_OPTIONS = [:title,:label_left,:label_right,:color_set] 

def initialize(** options)
options.each do | key,value |
raise未知选项#{key.inspect}unless(VALID_OPTIONS.include?(key))

$ b instance_variable_set(@#{key},value)
end
end

当你看到很多这些参数基础你可能想评估如果创建某种类结构对象和传递通过可能是一个更好的计划。这取决于您的代码的工作原理。


Is there an easy way to bulk assign instance variables

  def initialize(title: nil, label_left: nil, label_right: nil, color_set: nil)
    @title = title
    @label_left = label_left
    @label_right = label_right
    @color_set = color_set
  end

Can I loop/iterate through the initialize arguments and assign automatically?

解决方案

If you want specific variables, then not really. Using reflection here, even if it was available, would be trouble.

What you've got here is the most trivial case. Often you'll see code that looks more like this:

def initialize(title: nil, label: nil, label_width: nil, color_set: nil)
  @title = title.to_s
  @label = label_left.to_s
  @label_width = label_width.to_i
  @color_set = MyRGBConverter.to_rgb(color_set)
end

The initializer is a place where you can do any necessary conversion and validation. If some of those arguments are required to be certain values you'll have tests for that, raise an exception on an error and so forth. The repetitive code you have here in the minimal case often gets expanded and augmented on so there's no general purpose solution possible.

That leads to code like this:

def initialize(title: nil, label: nil, label_width: nil, color_set: nil)
  @title = title.to_s
  unless (@title.match(/\S/))
    raise "Title not specified"
  end

  @label = label_left.to_s
  unless (@label.match(/\A\w+\z/))
    raise "Invalid label #{@label.inspect}"
  end

  @label_width = label_width.to_i
  if (@label_width <= 0)
    raise "Label width must be > 0, #{@label_width} specified."
  end

  @color_set = MyRGBConverter.to_rgb(color_set)
end

If you really don't care about which arguments you're taking in then you can do this in Ruby 2.3 with the new keyword-arguments specifier **:

def initialize(**options)
  options.each do |key, value|
    instance_variable_set("@#{key}", value)
  end
end

Note that's potentially dangerous if those values are user supplied, so you might want to white-list them somehow:

VALID_OPTIONS = [ :title, :label_left, :label_right, :color_set ]

def initialize(**options)
  options.each do |key, value|
    raise "Unknown option #{key.inspect}" unless (VALID_OPTIONS.include?(key))

    instance_variable_set("@#{key}", value)
  end
end

Where you're seeing a lot of these arguments being passed in on a regular basis you might want to evaluate if creating some kind of struct-like object and passing that through might be a better plan. It depends on how your code works.

这篇关于ruby:大量初始化实例变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆