Аргументы метода Ruby — могут ли они автоматически изменять значение истинности?

#ruby #methods #parameters #arguments #truthiness

#ruby #методы #параметры #аргументы #правдивость

Вопрос:

У меня есть этот метод

 def forest(sword, armour, ring)
  

с его аргументами, имеющими true false значения или, которые я объявляю в основной программе как

 forest false, false, false
  

Если во время программы sword=true amp;amp; armour=true , есть ли какой-либо способ для Ruby автоматически оценить, являются ли аргументы true или false?
Могу ли я написать что-то вроде

 forest sword-truth-value, armour-truth-value, ring-truth-value?
  

Программа, которую я пишу, очень длинная, и для учета каждого отдельного случая потребуется слишком много строк кода.

Спасибо за помощь!

Комментарии:

1. Я не уверен, что понимаю вопрос, можете ли вы пояснить еще несколькими примерами?

2. Во время выполнения программы sword изменяет свое значение истинности. Вместо sword=false теперь sword=true и когда я снова напишу метод forest, я должен написать forest true, false, false . Но что, если бы я хотел, чтобы Ruby сообщал мне, является ли sword true или false? Есть ли какая-либо команда, которая может это сделать?

3. Думаю, теперь у меня есть идея, я буду работать над ответом ниже

4. Помните, что sword=true amp;amp; armor=true это присваивает обе переменные, а не тест. Если вы хотите сравнить, используйте == . При выполнении нескольких назначений не объединяйте их в цепочку amp;amp; , просто поместите их в несколько строк или сделайте sword = armor = true , если вы хотите, чтобы они были компактными.

Ответ №1:

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

 class Forest

  attr_accessor :sword, :armour, :ring

  def initialize(sword = false, armour = false, ring = false)
    @sword = sword
    @armour = armour
    @ring = ring
  end

end
  

Итак, теперь вы можете объявить экземпляр Forest ,

 forest = Forest.new
  

Все переменные по умолчанию false имеют значение, если вы явно не пишете true .

С attr_accessor помощью вы можете получить доступ ко всем переменным и задать их.

 forest.sword #=> false
forest.sword = true
forest.sword #=> true
  

Комментарии:

1. Большое вам спасибо за помощь! 🙂

Ответ №2:

Значения true и false являются атомарными. Если вы не хотите передавать их как литеральные значения, вам нужно установить переменную, т.е.

 is_sword = false
is_armor = false
is_ring = false
forest is_sword, is_armor, is_ring
  

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

    hash = { armor: false, sword: false, ring: false }
   def delete_nil_values(options)
     # delete all key-vals from the hash where the val is falsey
     options.each_key { |key| options.delete(key) if !options[key]}
     options
   end
   delete_nil_values(hash)
   puts hash
   # => {} 
   # it is empty
  

Это может быть или не быть тем, что вы намереваетесь; если вы хотите написать код без побочных эффектов, вы должны знать об этом.

Если вы «клонируете» ввод в верхней части delete_nil_values метода, используя options = Marshal.load(Marshal.dump(options)) его, он будет неизменяемым.

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