Robert Klemme
1/1/2006 5:08:00 PM
Christopher Campbell <spamoff.danx@ntlworld.com> 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
=> #<struct Tuple name="name", alias="alias">
>> t2=Tuple.new("name", "alias").freeze
=> #<struct Tuple name="name", alias="alias">
>> 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
=> #<Set: {}>
>> container << ["name", "alias"].freeze
=> #<Set: {["name", "alias"]}>
>> container << ["name", "alias"].freeze
=> #<Set: {["name", "alias"]}>
>> container << ["no name", "alias"].freeze
=> #<Set: {["name", "alias"], ["no name", "alias"]}>
>> container.each {|nm,al| print "name=", nm, " alias=", al,"\n"}
name=name alias=alias
name=no name alias=alias
=> #<Set: {["name", "alias"], ["no name", "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