Ссылающийся на хэш-элемент внутри себя

#ruby #ruby-1.9 #ruby-1.9.2

#ruby #ruby-1.9 #ruby-1.9.2

Вопрос:

У меня довольно короткий вопрос. Возможно ли инициализировать хэш чем-то вроде этого:

 row = {
    :title => "row title",
    :slug => row[:title].paremeterize
}
  

Другими словами, могу ли я каким-то образом ссылаться на неинициализированный хэш внутри себя, или я должен сделать это таким образом:

 row = {
    :title => "row title"
}
row[:slug] = row[:title].paremeterize
  

Спасибо за комментарии. Конечно, этот код не будет работать. Я спросил, есть ли аналогичный способ, возможно, с другим синтаксисом. Ruby был полон сюрпризов для меня 🙂

Комментарии:

1. Это кажется простым: «Вы пробовали это, и если да, то что происходит?» вопрос. Не хочу показаться язвительным, но что нам остается делать, кроме как попробовать это и сообщить вам, удастся это или нет?

Ответ №1:

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

 title = "foobar"

row = {
  :title => title,
  :slug => title.parameterize
}
  

Еще лучше…

 class Row
  attr_accessor :title

  def slug; title.parameterize; end
end

foo = Row.new :title => 'foo bar'
foo.slug    #=> "foo-bar"
  

Комментарии:

1. 1 за классовый подход. Может быть, вы имели в виду «строка класса < OpenStruct»?

2. Существует слишком много хороших способов сделать это. Я придерживался основных принципов, но класс, наследуемый от struct, вероятно, является хорошим вариантом, если каждая строка представляет собой просто структурированные данные.

Ответ №2:

Если вы запустите следующее в IRB,

 row = {
    :title => "row title",
    :slug => row[:title]
}
  

вы получаете ошибку NoMethodError: undefined method '[]' for nil:NilClass . Итак, нет, вы не можете этого сделать, учитывая, что на данный момент он row не был полностью инициализирован и является nil объектом.