From: Robert Klemme Date: 2006-01-02T02:12:56+09:00 Subject: Re: Tuples/Records/Quicky Objects + Read Only Arrays? Christopher Campbell wrote: > Hi, > > Does Ruby have a tuple or quicky object mechanism? I'm new to Ruby > and have become stuck on how to solve the following. Easiest is to use arrays. But you can as well use a Struct: >> Tuple=Struct.new :name, :alias => Tuple >> t1=Tuple.new("name", "alias").freeze => # >> t2=Tuple.new("name", "alias").freeze => # >> t1.name = "changed?" TypeError: can't modify frozen Struct from (irb):14:in `name=' from (irb):14 from ?:0 >> t1 == t2 => true > I'm testing adding items to a container, where each item is a pair of > strings. One is a name and another an alias. As they're added a > check should be performed to see if they're in the container, etc. I guess you rather want a Set so no multiple insertions can occur. Alternatively you can use a Hash with your tuple as key if there is a meaningful value. > I've been using OCaml for a while, and for this I'd just use a list of > tuples of strings. What's the ruby way of doing this? Iterating > over a container/array is a doddle, that's not the problem. The > problem is really can you have quick pairs without making classes and > so on? > While I'm at it, is there a read only array like container? Don't > want anyone messing with the internal array, they should not know > that what's returned is actually the internal representation or > fiddle with it. Don't care what they do with the elements in the > array, only the array itself. > > class X > def initialize > @elements = Array.new > end > > ... > > def elements > @elements.clone > end > end > > Returning a clone of an array is fine, just wondered if you could > "write-protect" stuff in general. Use #freeze as Florian pointed out. >> require 'set' => true >> container = Set.new => # >> container << ["name", "alias"].freeze => # >> container << ["name", "alias"].freeze => # >> container << ["no name", "alias"].freeze => # >> container.each {|nm,al| print "name=", nm, " alias=", al,"\n"} name=name alias=alias name=no name alias=alias => # >> container.each {|a| a << "does not work"} TypeError: can't modify frozen array from (irb):7:in `<<' from (irb):7 from /usr/lib/ruby/1.8/set.rb:189:in `each' from /usr/lib/ruby/1.8/set.rb:189:in `each' from (irb):7 from :0 HTH Kind regards robert