Using Tuples in Ruby?

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.

5

7 Answers

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 
6

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 
4

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"] 

I'm the author of Gem for Ruby tuples.

You are provided with two classes:

  • Tuple in general
  • Pair 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 tuple
  • first / last / second (only pair) - which returns a corresponding elements
  • [] that gives you an access to a particular elements
1

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" 
1

You can do something similiar with destructuring:

def something((a, b)) a + b end p something([1, 2]) 

This prints out 3 as expected.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like