рубиновый хеш с самореферентными элементами / рекурсивный хеш - PullRequest
0 голосов
/ 07 декабря 2009

Мне нужен рубиновый хеш H с ключами: a,: b,: c, чтобы H [: b] = H [: a] + 1; H [: c] = H [: b] + 2 и т. Д.

Как определить такой хеш в однострочном объявлении, например, H = {: a => 1,: b => H [: a] + 1,: c => H [: b] +2, ...}?

Мне нужно что-то похожее на объявление свойств DataMapper:

свойство: путь, FilePath

свойство: md5sum, String,: default => lambda {| r, p | Digest :: MD5.hexdigest (r.path.read)}

где: значение по умолчанию md5sum ссылается на свойство: path

Ответы [ 3 ]

0 голосов
/ 07 декабря 2009

Не ясно, чего вы пытаетесь достичь. Обратите внимание, что хэши могут иметь процедуру по умолчанию. Пример:

require 'digest/md5'
h = Hash.new do |hash, key|
  hash[:md5sum] = Digest::MD5.hexdigest(hash[:path]) if key == :md5sum
end

h[:path] = "/starway/to/heaven"
h[:md5sum]  # ==> "0e4faf226dac83569bde4fcf5bcd7ad6"
h[:md5sum] = "xyz"
h[:md5sum]  # ==> "xyz"
0 голосов
/ 15 февраля 2010

Звучит так, как будто вы хотите ленивые объявления: http://moonbase.rydia.net/software/lazy.rb/

0 голосов
/ 07 декабря 2009

Это лучшее, что я могу сделать:

arr = [[:a,1], [:b,1], [:c,2]]; H = {:temp => 0}
arr.inject(:temp) { |last, kv| H[kv[0]] = H[last] + kv[1]; kv[0] }
H.delete :temp

Довольно уродливо, и не так очевидно, что он делает. Я предлагаю вам просто сделать это простым способом, если это действительно не такая большая проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...