Как изменить число, переданное в метод в качестве аргумента - PullRequest
0 голосов
/ 19 февраля 2020

Фон

У меня есть метод, в котором я хочу изменить число, которое будет передано в метод, но не возвращено.

Пример

def increase_number_by_one_and_do_some_other_stuff(number)
    number = number + 1
    some_other_stuff = "Other stuff I want to happen in this function"
    some_other_stuff
end

number = 1

increase_number_by_one_and_do_some_other_stuff(number)

puts number
# => 1
## Expecting 2

Есть ли способ достичь этого в Ruby, или это всегда Pass by Value? Я пытался понять , как именно трактуются ссылки на объекты / значения в Ruby, но для моего уровня опыта это все еще довольно запутанно.

Больше контекста

Ситуация, которую я пытаюсь использовать это что-то вроде этого. Пытался сделать это простым, но все же дать достаточно информации.

total = 1000
unaccounted_for = 100
accounted_for = total - unaccounted_for

distribute_unaccounted(unaccounted_for, accounted_for)

puts unaccounted_for
# => 55
puts accounted_for
# => 945

def distributed_unaccounted(unaccounted_for, accounted_for)
   # lots of code
   category_a_reaccounted = 25 # calculated within this method
   category_b_reaccounted = 20 # calculated within this method
   total_reaccounted = category_a_reaccounted + category_b_reaccounted
   unaccounted_for -= total_reaccounted
   accounted_for += total_reaccounted
end

1 Ответ

1 голос
/ 19 февраля 2020

У меня есть метод, в котором я хочу изменить число ...

Числа являются неизменяемыми, вы не можете их изменить. 1 всегда будет 1.

Я думаю, что вы на самом деле хотите назначить новое значение переменной number в вашем методе и переменной number вне вашего метода.

Но это невозможно в Ruby. Переменные внутри ваших методов имеют свою собственную область видимости, и изменения не распространяются за пределы. Поэтому присвоение нового объекта переменной внутри вашего метода не повлияет на «внешние» переменные.

Есть ли способ достичь этого в Ruby ...

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

class Foo
  attr_reader :total, :unaccounted_for

  def initialize(total, unaccounted_for)
    @total = total
    @unaccounted_for = unaccounted_for
  end

  def accounted_for
    total - unaccounted_for
  end

  def category_a_reaccounted
    25 # actually calculated
  end

  def category_b_reaccounted
    20 # actually calculated
  end

  def distributed_unaccounted
    total_reaccounted = category_a_reaccounted + category_b_reaccounted
    @unaccounted_for -= total_reaccounted
  end
end

Использование, основанное на вашем примере:

foo = Foo.new(1000, 100)

foo.unaccounted_for #=> 100
foo.accounted_for   #=> 900

foo.distributed_unaccounted

foo.unaccounted_for #=> 55
foo.accounted_for   #=> 945
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...