Does anyone use tuples in Ruby? If so, how may one implement a tuple? Ruby hashes are nice and work almost as well, but I'd really like to see something like the Tuple class in Python, where you can use . notation to find the value for which you are looking. I'm wanting this so that I can create an implementation of D, similar to Dee for Python.
7 Answers
Brief example:
require 'ostruct' person = OpenStruct.new person.name = "John Smith" person.age = 70 person.pension = 300 puts person.name # -> "John Smith" puts person.age # -> 70 puts person.address # -> nil 6Based on the fact that you talk about hashes and . notation I'm going to assume you mean a different kind of tuple than the (1. "a") sort. You're probably looking for the Struct class. eg:
Person = Struct.new(:name, :age) me = Person.new me.name = "Guy" me.age = 30 4While this isn't strictly a tuple (can't do dot notation of members), you can assign a list of variables from a list, which often will solve issues with ruby being pass-by-value when you are after a list of return values.
E.g.
:linenum > (a,b,c) = [1,2,3] :linenum > a => 1 :linenum > b => 2 :linenum > c => 3 Arrays are cool to use as tuples because of destructuring
a = [[1,2], [2,3], [3,4]] a.map {|a,b| a+b } Struct give you convenient . accessors
Person = Struct.new(:first_name, :last_name) ppl = Person.new('John', 'Connor') ppl.first_name ppl.last_name You can get the convenience of both worlds with to_ary
Person = Struct.new(:first_name, :last_name) do def to_ary [first_name, last_name] end end # => [ Person.new('John', 'Connor'), Person.new('John', 'Conway') ].map { |a, b| a + ' ' + b } # => ["John Connor", "John Conway"] I'm the author of Gem for Ruby tuples.
You are provided with two classes:
Tuplein generalPairin particular
You can initialize them in different ways:
Tuple.new(1, 2) Tuple.new([1, 2]) Tuple(1, 2) Tuple([1, 2]) Tuple[1, 2] Both of the classes have some auxiliary methods:
length/arity- which returns number of values inside tuplefirst/last/second(only pair) - which returns a corresponding elements[]that gives you an access to a particular elements
You can mock the Scala tuples with this trick :
Tuple = Struct.new(:_1, :_2) 2.2.5 :003 > t = Tuple.new("a", "b") => #<struct Tuple _1="a", _2="b"> 2.2.5 :004 > t._1 => "a" 2.2.5 :005 > t._2 => "b" but here you can't have destructuring:
2.2.5 :012 > a, b = t => {:_1=>"a", :_2=>"b"} 2.2.5 :013 > a => {:_1=>"a", :_2=>"b"} 2.2.5 :014 > b => nil But thanks to this trick : destructuring will work:
2.2.5 :001 > Tuple = Struct.new(:_1, :_2) => Tuple 2.2.5 :002 > t = Tuple.new("a", "b") => #<struct Tuple _1="a", _2="b"> 2.2.5 :003 > t._1 => "a" 2.2.5 :004 > class Tuple ; def to_ary ; to_a ; end ; end => :to_ary 2.2.5 :005 > a, b = t => #<struct Tuple _1="a", _2="b"> 2.2.5 :006 > a => "a" 2.2.5 :007 > b => "b" 1You can do something similiar with destructuring:
def something((a, b)) a + b end p something([1, 2]) This prints out 3 as expected.