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 clas
I'm the author of Gem for Ruby tuples.
You are provided with two classes:
Tuple
in generalPair
in particularYou 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 elementsYou 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 : https://gist.github.com/stevecj/9ace6a70370f6d1a1511 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"
While 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"]
You can do something similiar with destructuring:
def something((a, b))
a + b
end
p something([1, 2])
This prints out 3
as expected.
OpenStruct?
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