为一个类的许多成员分配一个值

时间:2012-06-16 09:47:05

标签: ruby arrays

class A
  attr_accessor :dab
  ....
end

现在我有一个A的实例数组,比如说

arr = [A.new, A.new, A.new]

现在我想为数组A中存在的类arr的所有实例设置一个值。 ruby / rails中有一个快捷方式吗?

此外,我确实A继承自ActiveRecord::Base

我的实际需要是:

A.find_all_by_some_condition.all.dabs = 2

因此,所有找到的对象都将dab设置为2。

这有什么捷径吗?

2 个答案:

答案 0 :(得分:1)

要从数组中获取A类的项目,可以使用select / find_all

arr.select { |el| el.class == A }arr.select { |el| A === el }

虽然您希望为多个对象分配值,而不是相应的类,但要实现实际结果。 A类没有定义实际的对象,它只定义了对象在创建时使用的蓝图。所以找到一种方法来分配A的所有实例的值并不是你想要的(虽然我可能已经错过了你所要求的点)

要为一个对象数组赋值,这有效:

A.find_all_by_some_condition.each { |a| a.dab = 2 }

也许你想在那之后保存它们,现在arr.each(&:save)可能会派上用场。如果您不知道它,请查看&符号。非常有用。

答案 1 :(得分:0)

默认情况下你不能直接这样做,但你可以使用Ruby method_missing构建类似的东西。

两种解决方案:

解决方案1 ​​ - 使用包装类

我们将此类MArray称为多分配数组。

class MArray
  def initialize(inner_array)
    @inner = inner_array
  end

  def method_missing(meth, value)
    # Check if assignement, and if it is then run mass-assign
    if meth.to_s =~ /^\w+=$/
      @inner.each { |itm| itm.send(meth, value) }
    else
      raise ArgumentError, "MArray: not an assignment"
    end
  end
end

我们还需要在MArray中添加对Array的支持,以便进行换行。我们将方法mas称为“质量分配”:

class Array
  def mas
    # Wrap MArray around self
    MArray.new(self)
  end
end

用法很简单:

Blob = Struct.new(:dab)
arr = [Blob.new] * 3
arr.mas.dab = 123
arr
=> [#<struct Blob dab=123>, #<struct Blob dab=123>, #<struct Blob dab=123>]

解决方案2 - 直接在Array

中创建质量指配支持

由于我们直接修改了method_missing中的Array,因此这有点“危险”。 可以创建一些奇怪的副作用(例如,如果某个其他库已经重新定义了method_missing,或者您不小心意外调用了大量分配)。

它的工作原理是尝试检测具有复数单词的分配(以s结尾的单词),然后触发批量分配:

class Array
  def method_missing(meth, *args, &block)
    # Check for plural assignment, and as an added safety check also
    # see if all elements in the array support the assignment:
    if meth.to_s =~ /^(\w+)s=$/ && 
       self.all? { |itm| itm.respond_to?("#{$1}=") }
      self.each { |itm| itm.send("#{$1}=", *args) }
    else
      super
    end
  end
end

然后用法变得比MArray更短:

Blob = Struct.new(:dab)
arr = [Blob.new] * 3
arr.dabs = 123
arr
=> [#<struct Blob dab=123>, #<struct Blob dab=123>, #<struct Blob dab=123>]