После передачи ссылки на метод, любые моды, использующие эту ссылку, не видны вне метода - Ruby? - PullRequest
1 голос
/ 11 мая 2010

Я передаю ссылку name на mod_name , я изменяю ссылочный объект изнутри метода, но изменение не видно вне метода, если я ссылаюсь на один и тот же объект из всех мест, почему значение отличается в зависимости от того, где я на него ссылаюсь?

name = "Jason"

puts name.object_id      #19827274

def mod_name(name)
  puts name.object_id    #19827274
  name = "JasonB"
end

puts name.object_id      #19827274

puts name                #Jason

Строка может быть плохим примером, но я получаю тот же результат, даже если я использую Fixnum.

Ответы [ 4 ]

3 голосов
/ 11 мая 2010

Как упоминает Грег, в вашем примере вы создаете новую локальную переменную с именем name, которая скрывает ваш параметр. Это связано с поведением, называемым копирование при записи . Если вы хотите, чтобы функция влияла на объект, на который ссылаются параметры, вы могли бы использовать replace вместо выполнения присваивания, например:

def mod_name(name)
  name.replace('JasonB')
end
1 голос
/ 11 мая 2010

Я думаю, что вы получили ответы на заданный вопрос. Может быть, вам нужен ответ на то, что заставило бы вас задать этот вопрос.

name = "jason"

def mod_name(name)
  local_name = "jasonb"
end

puts name = mod_name(name)
puts name

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

@name = "jason"

def mod_name()
  @name = "jasonb"
end

puts @name
1 голос
/ 11 мая 2010

изменяет содержимое строки:

def mod_name(name)
  print "%i %s\n" % [name.object_id, name]
  name[0..-1] = "what"
  print "%i %s\n" % [name.object_id, name]
  name << "ever"
  print "%i %s\n" % [name.object_id, name]
end

Также:

  • в вашем примере кода вы никогда не вызываете функцию mod_name.

  • Вы, похоже, полагали, что написание 'var = x' изменит содержимое var. Не может Это может изменить только то, на что объект указывает var. Запрос его object_id до и после воздействия показал бы, что это действительно другая строка.

  • Невозможно заставить эту функцию работать с Fixnums, потому что Fixnums неизменны в ruby. Вы не можете вносить какие-либо изменения в Fixnum. Хуже того, они даже не передаются по ссылке и в некоторых угловых случаях не будут вести себя как правильные объекты.

0 голосов
/ 11 мая 2010

В этом случае строка name = "JasonB" создает новую локальную переменную с именем name и присваивает ей "JasonB", а не изменяет строку, которая была передана.

...