Используете кортежи в Ruby?

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


person Community    schedule 08.02.2009    source источник
comment
Вы когда-нибудь реализовывали D в Ruby? Если да, то есть ли у вас на это ссылка? Недавно я работал над чем-то подобным и хотел бы увидеть, что вы уже сделали.   -  person dkubb    schedule 15.12.2009
comment
Неа; Я никогда не заходил так далеко. Я искал несколько других вещей, пытаясь вернуться к этому. Я нашел несколько библиотек, которые, похоже, могут помочь: LazyList и arel. Я в основном пришел к выводу, что LINQ в .NET почти на месте, затем нашел arel, который тоже был близок. Использование LazyList и удаление прямого преобразования в SQL, последнее из которых также является целью проекта, почти приведут вас к этому. Тем не менее, я хотел бы увидеть то, что у вас есть на данный момент. Я все еще немного далек от того, чтобы вернуться к этому.   -  person    schedule 19.12.2009
comment
ambition - еще одна интересная библиотека, но она не обновлялась какое-то время. Это я нашел первым. arel, похоже, продолжает ту же традицию.   -  person    schedule 19.12.2009
comment
Я только начал работать над этим проектом под названием veritas: github.com/dkubb/veritas Это все еще действительно рано. Если все пойдет хорошо, я могу обновить DataMapper, чтобы использовать его в качестве основы. Я не очень заинтересован в поддержке синтаксиса, подобного Ambition, в ядре, поскольку вы можете использовать ParseTree только с 1.8, но у меня не было бы проблем с плагином, подобным тому, который я написал для DataMapper: github.com/dkubb/dm-ambition   -  person dkubb    schedule 04.01.2010
comment
Я должен добавить, что я рассматриваю возможность обновления базовой реализации, чтобы использовать объекты Struct для кортежей, чтобы оптимизировать использование памяти, но на данный момент меня больше беспокоит правильность и спецификация общедоступного API.   -  person dkubb    schedule 04.01.2010


Ответы (7)


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
person Community    schedule 08.02.2009
comment
Это именно то, что я искал. Спасибо! - person ; 09.02.2009
comment
np :) чтобы ответить на ваш вопрос: нет, я не использую кортежи в ruby, как openstructs или иначе. я использую классы на верхнем уровне и хеши на нижнем уровне :) - person ; 09.02.2009
comment
это плохой ответ, просто ссылка? Шутки в сторону? что произойдет, если / когда ссылка станет неработающей? - person ; 31.10.2013
comment
это даже не понятие Tuple, которое вы раскрываете здесь. Просто структура данных. Не могу понять, почему ваше решение получает больше всего голосов - person Jules Ivanic; 06.12.2016
comment
@JulesIvanic действительный комментарий, но иногда OP не знает, как правильно сформулировать заголовок для вопроса, в данном случае это на самом деле ответ, который ищет OP :) - person SidOfc; 16.10.2017

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

Person = Struct.new(:name, :age)
me = Person.new
me.name = "Guy"
me.age =  30
person Logan Capaldo    schedule 08.02.2009
comment
Это близко, но меня беспокоит необходимость называть это. Я искал что-то вроде сортировки (1. a), но с описанной вами нотацией свойства get / set. - person ; 09.02.2009
comment
@panesofglass, не надо ничего называть: a = Struct.new (: name,: age) .new; a.name = Парень - person paradoja; 09.02.2009
comment
Могу ли я установить a = Struct.new(:name, :age), а позже сказать a.new? Я бы так предположил. Я должен это проверить. Было бы намного более ясно, чего я хочу. - person ; 27.07.2010
comment
Обнаружив это годы спустя, я могу подтвердить, что Person.new("Guy", 30) действительно работает в дополнение к настройке полей по отдельности. - person Greg Haskins; 29.04.2014

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

E.g.

:linenum > (a,b,c) = [1,2,3]
:linenum > a
  => 1
:linenum > b
  => 2
:linenum > c
  => 3
person e_m0ney    schedule 30.04.2014

Я автор Gem for Ruby tuples.

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

  • Tuple в целом
  • Pair в частности

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

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

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

  • length / arity - возвращает количество значений внутри кортежа
  • first / last / second (только пара) - возвращает соответствующие элементы
  • [], который дает вам доступ к определенным элементам
person Kamil Lelonek    schedule 12.06.2015

Массивы круто использовать в качестве кортежей из-за деструктуризации

a = [[1,2], [2,3], [3,4]]
a.map {|a,b| a+b }

Struct предоставляет вам удобные . средства доступа

Person = Struct.new(:first_name, :last_name)
ppl = Person.new('John', 'Connor')
ppl.first_name 
ppl.last_name

Вы можете получить удобство обоих миров с 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"]
person Cyril Duchon-Doris    schedule 05.02.2020

Вы можете издеваться над кортежами 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"
person Jules Ivanic    schedule 06.12.2016
comment
Это можно сделать немного менее запутанным, просто определив метод деструктивного доступа в блоке, переданном в Struct.new, например, ghostbin.com/ paste / vwtg6 - person dynsne; 10.06.2018

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

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

p something([1, 2])

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

person KARASZI István    schedule 26.05.2015