Рекурсивная функция в задачах определения вспомогательного метода - PullRequest
0 голосов
/ 21 сентября 2011

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

Итак, в моем контроллере приложений есть что-то вроде этого (build html):

def create_comments_list(comment, commentlist)
  commentlist += "<div class=\"comment\" style=\"padding-left:20px;\"><div style=\"display:none;\" class=\"parent_id\">#{comment.id}</div>#{comment.user.name}:<br/><div class=\"ccontent\">#{comment.content}</div><br/><a href=\"#reply\" class=\"reply\" style=\"color:black;\">Reply</a>";
  children = comment.children
  children.each do |c|
    create_comments_list(c, commentlist)
  end
  commentlist += "</div><div class=\"shortdivider\">&nbsp;</div>"
  commentlist
end

И я вызываю в контроллере так:

@commentlist = create_comments_list(c, @commentlist)

Кажется, что выполняется полная рекурсия ... однако в случае 1 родительского комментария и 1 дочернего комментария список комментариев только выплевывает родительский комментарий. Если я регистрирую вещи, я вижу, что дочерний элемент действительно добавляется в @commentlist внутри рекурсивного вызова, но когда он раскручивается туда, где родительский объект ввел рекурсию, переменная commentlist больше не содержит дочерний элемент. Похоже, я не понимаю область действия этих переменных ... Мне нужен коммент-лист, чтобы сохранить его значение после того, как он откатывается от внутреннего вызова рекурсии. Кто-нибудь может пролить свет? (Или какие-то лучшие способы сделать это? У меня в голове зазвонил плохой стиль)

1 Ответ

2 голосов
/ 21 сентября 2011

Используйте оператор лопатки << вместо +=, если хотите изменить аргумент commentslist.

+= создает новый строковый объект и присваивает его вашей переменной, но функциидалее в стеке все еще есть ссылка на более старое строковое значение.<< изменяет существующий строковый объект.

a = "foo"   # => "foo"
a.object_id # => 69847780
a += "bar"  # => "foobar"
a.object_id # => 69786550 (note this is not the same object as before)

b = "foo"   # => "foo"
b.object_id # => 69764530
b << "bar"  # => "foobar"
b.object_id # => 69764530
...