Использование кортежей в Ruby? - PullRequest
55 голосов
/ 08 февраля 2009

Кто-нибудь использует кортежи в Ruby? Если так, как можно реализовать кортеж? Хэши Ruby хороши и работают почти так же хорошо, но мне бы очень хотелось увидеть что-то вроде класса Tuple в Python, где вы можете использовать нотацию ., чтобы найти значение, которое вы ищете. Я хочу этого, чтобы я мог создать реализацию D , аналогичную Ди для Python.

Ответы [ 6 ]

46 голосов
/ 08 февраля 2009

OpenStruct

Краткий пример:

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
26 голосов
/ 08 февраля 2009

Исходя из того, что вы говорите о хешах и др. примечание Я собираюсь предположить, что вы имеете в виду кортеж другого типа, чем (1. "a"). Вы, наверное, ищете класс Struct. например:

Person = Struct.new(:name, :age)
me = Person.new
me.name = "Guy"
me.age =  30
12 голосов
/ 30 апреля 2014

Хотя это не совсем кортеж (не может делать точечную запись членов), вы можете назначить список переменных из списка, что часто решает проблемы с передачей ruby ​​по значению, когда вы список возвращаемых значений.

например.

:linenum > (a,b,c) = [1,2,3]
:linenum > a
  => 1
:linenum > b
  => 2
:linenum > c
  => 3
8 голосов
/ 12 июня 2015

Я автор Gem для кортежей Ruby .

Вам предоставляется два класса:

  • Tuple в общем
  • Pair в частности

Вы можете инициализировать их различными способами:

Tuple.new(1, 2)
Tuple.new([1, 2])
Tuple(1, 2)
Tuple([1, 2])
Tuple[1, 2]

Оба класса имеют несколько вспомогательных методов:

  • length / arity - возвращает количество значений внутри кортежа
  • first / last / second (только пара) - возвращает соответствующие элементы
  • [], который дает вам доступ к определенным элементам
5 голосов
/ 06 декабря 2016

С трюком можно издеваться над кортежами Scala:

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"

но здесь не может быть разрушения:

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

Но благодаря этому трюку: https://gist.github.com/stevecj/9ace6a70370f6d1a1511 деструктура будет работать:

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"
3 голосов
/ 26 мая 2015

Вы можете сделать что-то похожее на разрушение:

def something((a, b))
  a + b
end

p something([1, 2])

Это печатает 3, как и ожидалось.

...