Обновление: теперь я понимаю, что мой вопрос должен быть: как передать аргумент по ССЫЛКЕ? У меня есть подсказка: «передать параметр по ссылке» в Ruby? но Не знаю, возможно ли это вообще. Возможно, стоит закрыть этот вопрос.

В отношении этого предыдущего вопроса: Как отменить связанный список в Ruby < / а>

Я немного сбит с толку, почему список не перевернут.

Итак, я ожидал, что: print_values(node3)

Первоначально дал бы: 12 -> 99 -> 37 -> nil

А потом, когда я позвоню: reverse_list(node3)

Я бы ожидал, что позвонят в print_values(node3), чтобы сообщить 37 -> 99 -> 12 -> nil

Однако вместо этого я получаю 12 -> nil

В некоторой степени это имеет смысл, потому что объект, на который ссылается node3, все еще имеет значение 12 и имеет значение nil для next_node, но есть ли способ полностью перевернуть список в Ruby?

Похоже, что здесь есть что-то об изменчивости с рубином, что я не совсем понимаю. Как будто с каждым новым добавлением к стеку памяти / вызову функции мы получаем новые объекты? Были бы очень признательны за некоторые пояснения.

Я также создал свой собственный метод, чтобы попытаться заставить функциональность работать на месте:

def reverse_list(list, previous=nil)

    rest_of_list = list.next_node
    print "rest of list: "
    print_values(rest_of_list)
    list.next_node = previous
    previous = list
    print "new previous: "
    print_values(previous)  
    list = rest_of_list
    print "new list: "
    print_values(list)
    if list.nil?
        print "list now nil\n"
        list = previous
        print "updated list: "
        print_values(list)
        return list
    else
        reverse_list(list, previous)
    end
end
1
Ramy 3 Янв 2016 в 22:17

2 ответа

Лучший ответ

В ответ на ваш обновленный вопрос:

Да, вам придется перевернуть значения списка вместо указателей.

Чтобы сделать это AFAIK, вы должны сначала создать новый перевернутый список, а затем скопировать перевернутые значения обратно в исходный список.

Я обновил исходный код, сделав его более рубиновым (т.е. методы являются частью класса списка, а суффикс «!» Используется для указания того, что метод изменит объект (а не просто вернет новое значение).

<script type="text/ruby">
def print(s)
  s = s.gsub("\n", "<br/>").gsub(" ", "&nbsp;")
  Element['#output'].html = Element['#output'].html + s
end

class LinkedListNode
  attr_accessor :value, :next_node

  def initialize(value, next_node=nil)
    @value = value
    @next_node = next_node
  end
 
  def reverse_list(reversed=nil)
    if next_node
      next_node.reverse_list(LinkedListNode.new(value, reversed))
    else
      LinkedListNode.new(value, reversed)
    end
  end
  
  def reverse_list!(list=self, reversed_list = reverse_list)
    self.value = reversed_list.value
    if next_node
      next_node.reverse_list!(list, reversed_list.next_node)
    else
      list
    end
  end
  
  def print_values
    print "[#{object_id}]#{value} --> "
    if next_node.nil?
      print "nil\n"
    else
      next_node.print_values
    end
  end
 
end

node1 = LinkedListNode.new(37)
node2 = LinkedListNode.new(99, node1)
node3 = LinkedListNode.new(12, node2)
print "original list:     "
node3.print_values
print "reversed list:     "
node3.reverse_list.print_values
print "reversed in place: "
node3.reverse_list!
node3.print_values

</script>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/reactrb/reactrb-express/master/reactrb-express.js"></script>
<div id="output" style="font-family: courier"></div>
1
Mitch VanDuyn 25 Авг 2016 в 11:38

В Ruby нет передачи по ссылке

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

1
Mitch VanDuyn 4 Янв 2016 в 00:38