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.

- 15,092
- 13
- 71
- 136
-
Did you ever implement D in Ruby? If so, do you have the link to it? I've been working on something similar recently, and I'd love to see what you've done so far. – dkubb Dec 15 '09 at 09:10
-
1Nope; I never made it that far. I've been winding my way around several other things trying to get back to it. I did find several libraries that seem as though they would help: LazyList and arel. I basically came to the conclusion that LINQ in .NET was almost there, then found arel, which was also close. Using LazyList and removing the direct-to-SQL conversion, the latter of which is also a project goal, would almost get you there. That said, I would love to see what you have so far. I'm still a little way off from getting back to it. – Dec 19 '09 at 05:32
-
ambition is another interesting looking library, but it hasn't been updated in some time. That was the one I found first. arel looks like it has continued in the same tradition. – Dec 19 '09 at 05:57
-
I've just begun a project called veritas to work on this: http://github.com/dkubb/veritas It's still *really* early. If things go well I may update DataMapper to use it as a foundation. I'm not really interested in supporting Ambition-like syntax in the core, since you can only use ParseTree with 1.8, but I wouldn't have a problem with a plugin like the one I wrote for DataMapper: http://github.com/dkubb/dm-ambition – dkubb Jan 04 '10 at 07:41
-
I should add that I'm considering updating the underlying implementation to use Struct objects for the tuples to optimize memory usage, but at the moment I'm more concerned about correctness and speccing out the public API. – dkubb Jan 04 '10 at 07:43
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

- 1,884
- 4
- 21
- 37
-
2np :) to answer you question though: no i do not use tuples in ruby, as openstructs or otherwise. i use classes at the high end and hashes at the low end :) – Feb 09 '09 at 11:01
-
10this is a poor answer, just a link? Seriously? what happens if/when the link becomes broken? – Oct 30 '13 at 22:26
-
2it's not even the notion of Tuple you expose here. Just a data structure. Can't understand how your solution is the most upvoted – Jules Ivanic Dec 06 '16 at 15:39
-
2@JulesIvanic valid comment but sometimes an OP does not know how to properly formulate a title for a question, in this case this is actually the answer that the OP is looking for :) – SidOfc Oct 16 '17 at 12:30
-
I know this question has been edited to have a proper answer, but I'd just like to acknowledge that the link is now broken. – Pieter-Jan Briers Jul 26 '23 at 13:58
Based 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

- 39,555
- 5
- 63
- 78
-
1That's close, but having to name it bugs me. I was looking for something like the (1. "a") sort but with the property get/set notation you describe. – Feb 08 '09 at 22:02
-
6@panesofglass, there's no need to name nothing: a = Struct.new(:name, :age).new; a.name = "Guy" – paradoja Feb 09 '09 at 00:56
-
Can I set `a = Struct.new(:name, :age)` and later say a.new? I would suppose so. I'll have to check that out. It would be a lot more explicit as to what I want. – Jul 26 '10 at 22:02
-
5Finding this years later, I can confirm that `Person.new("Guy", 30)` does work in addition to setting the fields individually. – Greg Haskins Apr 29 '14 at 11:42
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

- 978
- 9
- 14
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"]

- 12,964
- 9
- 77
- 164
I'm the author of Gem for Ruby tuples.
You are provided with two classes:
Tuple
in generalPair
in 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

- 14,592
- 14
- 66
- 90
-
What is the difference between all the initializers? Or are they all equivalent? (which I suppose) If known from functional programming, which would be an examplary language that uses this syntax? – sb813322 Jan 16 '23 at 12:10
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 : 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"

- 1,579
- 2
- 15
- 28
-
1This could be made a little less confusing by simply defining the destructing accessor method in a block passed to `Struct.new` like https://ghostbin.com/paste/vwtg6 – dynsne Jun 10 '18 at 01:35
You can do something similiar with destructuring:
def something((a, b))
a + b
end
p something([1, 2])
This prints out 3
as expected.

- 30,900
- 8
- 101
- 128