Вот простой ответ:
В рубина вы передаете переменные с объектами по ссылке. Когда вы назначаете Object переменной, эта переменная не содержит в себе самого объекта. Вместо этого он содержит только ссылку на этот объект.
Это может помочь вам увидеть различия между ссылками и объектами, чтобы понять, как отправлять переменные в качестве параметров: сам объект не находится в переменной, эта переменная указывает на ссылку объекта в из-за этого, если одна переменная указывает на другой объект и изменяет его, это не означает, что он изменил объект, о котором он ранее ссылался.
Важно понять, что параметр bar в методе foo действительно является лишь ссылкой на объект в памяти, а не сам объект. Поэтому, если бар однажды указал на объект, но теперь ссылается на другой объект, он будет изменять то, на что он ссылается, а не предыдущий объект, на который он указал. Вот код последнего test.rb прокомментировал немного для вас, чтобы лучше понять его:
def foo(bar) # here "bar" points to the same object as "hash_test"
pre_defined = {'key' => 'value'} # here a new object is created and referenced
bar = pre_defined # now "bar" points to a new object and forgets about "hash_test"
end
def my_print(a) # here "a" holds a reference to "hash_test" which is empty
a.each{|k,v| # "a" is empty, so it has nothing to put
puts "#{k} => #{v}"
}
end
Я надеюсь, что это помогает. Если вам нужно что-то более подробное:
Причина, по которой ваша последняя версия test.rb печатает пустой хэш в test_drive.rb, состоит в том, что объект Hash, на который указывает ссылка «hash_test», на самом деле не изменяется на все.Вместо этого метод foo, в то время как первоначально получая в качестве параметра под названием «bar» ссылку на объект Hash, на который указывает «hash_test», быстро заменяет эту ссылку в «баре» новой ссылкой на новый Hash Object, pre_defined "переменная указывает на. Теперь «bar» не указывает на тот же объект, что и «hash_test», и поэтому объект, который указывает «hash_test», никогда не изменяется. Таким образом, объект Hash, содержащий «hash_test», никогда не заполняется ничем и пуст, когда my_print пытается его распечатать.
Спасибо! Это действительно помогает. Но сказано, что переменная, тип/класс которой является fixnum, true/false и т. Д., Содержит в ней значение. Это правильно? – fabregaszy
Как я понял, в Ruby у вас нет примитивных типов. Переменная, которая считается типом класса Fixnum, на самом деле является ссылкой на экземпляр Fixnum, который представляет собой целое число. Ruby реализован на C, поэтому примитивы do существуют за кулисами, но нет способа получить доступ к чистым примитивным типам в коде Ruby, насколько я знаю. Перейдите в irb и попробуйте a = 5 и b = 5, затем выполните a.object_id. Они оба относятся к одному и тому же объекту: a.object_id, b.object_id, try 5.object_id, а также 5.class, 5. методы. – Andres
Просто для подтверждения, Fixnum и True/False являются объектами. Просто попробуйте этот небольшой фрагмент в irb для подтверждения: 5.class.ancestors, а также true.class.ancestors и false.class.ancestors – Andres