【问题标题】:Multiple initialization of auto-vivifying hashes using a new operator in Ruby在 Ruby 中使用 new 运算符对自动激活哈希进行多次初始化
【发布时间】:2010-07-02 11:43:43
【问题描述】:

我想用一行表达式初始化几个auto-vivifying hashes。到目前为止,我为AutoHash 对象找到了一个额外的方法:

class AutoHash < Hash
  ...
  def few(n=0)
    Array.new(n) { AutoHash.new }
  end

这让我可以做以下事情

a, b, c = AutoHash.new.few 3

但是,我觉得可以通过定义一个新的运算符:=来使下面的句子成为可能

a := b := c = AutoHash.new

你能帮我实现这个吗?


我必须使用superators吗?

require 'superators'

class AutoHash < Hash
  ...
  superator ":=" do |operand|
    if operand.kind_of? Hash
      ...
    else
      ...
    end
  end

更新: 现在我看到需要在类之外定义运算符。是否可以定义这样的对象克隆操作符?


Update2 方法few的更清晰定义,感谢Joshua


参考文献

  1. http://www.linux-mag.com/cache/7432/1.html
  2. Does Ruby support var references like PHP?
  3. http://ruby.about.com/od/advancedruby/a/deepcopy.htm

【问题讨论】:

  • 您意识到您当前的 a = b = c = AutoHash.new.few 3 将使所有变量引用相同的哈希实例?如果您不希望这样, := 运算符的实现可能需要调用 clone() 并且您会遇到通常的“我想要深度克隆吗?”问题。
  • 操作,抱歉。我已经修好了。谢谢

标签: ruby hash initialization reference autovivification


【解决方案1】:

你在哪里要求a := b := c := AutoHash.new.few 3我认为(不确定我是否理解你的愿望)你真的想要a,b,c=Autohash.new.few 3


为什么很少人使用可变参数,而您只使用第一个?

我还发现您创建的返回值令人困惑,也许可以尝试

def few(n=0) 
  Array.new(n) { AutoHash.new } 
end 

除此之外,few 似乎应该是一个类方法。 a,b,c=AutoHash.few 3 如果您在课堂上定义很少,这将起作用:

def AutoHash.few(n=0)
  Array.new(n) { AutoHash.new }
end

如果 a,b,c=AutoHash.few 3 不是您想要的,并且您真的想要实现自己的运算符,那么请查看 Hacking parse.y,它是在 RubyConf 2009 上发表的演讲。您可以在 http://rubyconf2009.confreaks.com/19-nov-2009-17-15-hacking-parsey-tatsuhiro-ujihisa.html 观看演示文稿,您可以在 http://www.slideshare.net/ujihisa/hacking-parsey-rubyconf-2009 观看幻灯片

【讨论】:

  • 约书亚,感谢您的回答。确实不需要可变参数(只是一个坏习惯)。我想使用a := b := c = AutoHash.new 进行初始化(我可能在你输入的时候改变了我的问题)
  • 我不明白 := 运算符应该做什么。我已多次阅读该问题的新版本。旧版本让我觉得你想要a,b,c 给出的行为。但现在我不能说。
  • 基本上,我想要一个用于深度克隆对象的魔术运算符。这样a := b := c = AutoHash.new 就会给我三个不相关的哈希值。到目前为止,我必须使用我班级的few 方法,这不太方便。
  • 我明白了。您将遇到的一个问题是 Ruby 对深度复制的支持很差(可能部分是因为 - 没有完全的不变性 - 这个概念本身存在某些严重的问题 - 但它可能会更好)。您有用于生成浅拷贝的 dup 和 clone 方法,并且有一些使用编组的繁琐解决方法。无论您采用哪种方法,都需要解决这个问题。
  • 这里有一个潜在的替代方案pastie.org/private/ayj1vglvadv5bf8orza 它将少数方法添加到对象中,然后可供所有人使用。如果很少调用它的对象是一个类,则使用该类的新实例填充数组,否则,它将复制该对象。要获得深层复制行为,您必须在您使用的每个对象中定义这对您意味着什么。在这里,我为 AutoHash 编写了自己的 dup 方法,该方法也可以复制键和值。并且它将第一个参数作为创建数量,其余/任何块都被转发。
猜你喜欢
  • 1970-01-01
  • 2010-12-02
  • 1970-01-01
  • 2012-03-20
  • 2015-03-11
  • 2012-03-25
  • 2017-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多