views:

41

answers:

1

I would like to initialize several auto-vivifying hashes by one-line expression. So far I came to an extra method for the AutoHash object:

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

which allows me to do the following

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

However, I feel that one can make the following sentence possible by defining a new operator :=

a := b := c = AutoHash.new

Could you help me to implement this?


Do I have to use superators?

require 'superators'

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

Update: Now I see that the operator needs to be defined outside the class. Is it possible to define such object clone operator?


Update2 More clear definition of method few, thanks to Joshua


References

  1. http://www.linux-mag.com/cache/7432/1.html
  2. http://stackoverflow.com/questions/460663/does-ruby-support-var-references-like-php
  3. http://ruby.about.com/od/advancedruby/a/deepcopy.htm
+1  A: 

Where you ask for a := b := c := AutoHash.new.few 3 I think (not sure I understand your desire) that you really want a,b,c=Autohash.new.few 3


Why does few take variable args, when you only ever use the first?

I also find your creation of the return value to be confusing, maybe try

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

Beyond that, it seems like few should be a class method. a,b,c=AutoHash.few 3 which will work if you defined few on the class:

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

If a,b,c=AutoHash.few 3 isn't what you're looking for, and you really want to implement your own operator, then check out Hacking parse.y, which was a talk given at RubyConf 2009. You can watch the presentation at http://rubyconf2009.confreaks.com/19-nov-2009-17-15-hacking-parsey-tatsuhiro-ujihisa.html and you can see the slides at http://www.slideshare.net/ujihisa/hacking-parsey-rubyconf-2009

Joshua Cheek
Joshua, thanks for the answer. Variable args are not needed indeed (just a bad habit). I want to use `a := b := c = AutoHash.new` for initialization (I have probably changed my question when you were typing)
Andrey
I don't understand what the := operator is supposed to do. I have read the new version of the question several times. The old version made me think you wanted the behaviour that `a,b,c` gives. But now I cannot tell.
Joshua Cheek
Basically, I want a magic operator for deep cloning of objects. So that the sentence `a := b := c = AutoHash.new` would give me three not-related hashes. So far I have to use `few` method of my class for that, which is less convenient.
Andrey
I see. One problem you will have is that Ruby has poor support for deep copying (probably in part because -- without complete immutability -- the concept itself suffers from certain serious issues -- but still, it could be much better). You have the dup and clone methods for generating shallow copies, and there is some sort of cumbersome workaround using marshalling. Regardless of which approach you take, this will need to be addressed.
Joshua Cheek
Here is a potential alternative http://pastie.org/private/ayj1vglvadv5bf8orza It adds the few method to object, then it is available to everyone. If the object having few invoked on it is a class, then populates the array with new instances of that class, otherwise, it dups the object. To get deep copy behaviour, you have to define what that means for you in each object you are using. Here I wrote my own dup method for AutoHash that also dups keys and values. And it takes the first arg as how many to create, and the rest / any blocks get forwarded on.
Joshua Cheek
Thanks for your help, Joshua! I have decided to open a new question instead http://stackoverflow.com/questions/3171118/how-to-create-an-operator-for-deep-copy-cloning-of-objects-in-ruby
Andrey