Есть ли способ написать с операторами следующее:
if A is true
then A = A
elsif if B is true
then A = B
else
A = C
end
Только B или C будут иметь значение в любой момент времени. Иногда A будет иметь значение, иногда нет.
Я думал что-то вроде A ||= (B || C), но в результате получаю какие-то странные действия.
Спасибо.
Обновлено: примечание** Я явно задал плохой вопрос. Вступая, я подумал, что это просто вопрос операторов/логики, а переменная/константы не имеют значения для решения. Спасибо всем за ваши отзывы не только по моему вопросу, но и по формату моего вопроса. Я постараюсь быть более полным. **примечание
Фон: я пытался создать систему входа в систему, в которой сеанс определялся типом входа пользователя в систему. Существует два типа пользователей: «B» и «C», и «A» будет определено, если пользователь уже вошел в систему. , Хотя прогулка:
если пользователь уже вошел в систему, не меняйте значение "А" wlseif пользователь входит в систему как пользователь типа "B", установите значение «A» для учетных данных сеанса B иначе пользователь входит в систему как пользователь типа "C", установите значение «A» для учетных данных сеанса C конец
Первоначально у меня был один тип пользователя, и я использовал этот код:
def current_user
@current_user ||= User.find_by(id: session[:user_id])
end
Я хотел расширить логику этого оператора. Однако, когда я реализовал варианты A ||= (B || C)
, произошло одно из двух. Либо пользователь не сможет войти в систему, либо, если пользователь уже вошел в систему, он не сможет выйти из системы. то есть сеансы не могли быть созданы, не могли быть очищены или удалены. Именно это странное поведение я и имел в виду.
«Решение»: Тем не менее, мне удалось придумать обходной путь, подробно описанный ниже.
Обходной путь, который я нашел для своего вопроса, заключался в том, чтобы вернуться к одной пользовательской модели вместо двух. Затем добавьте в мою пользовательскую модель дополнительный столбец, в котором указан тип пользователя. Таким образом, исходный код будет работать, и я смогу контролировать свой пользовательский интерфейс на основе этого «столбца управления».
Вы должны включить фактические данные в свой вопрос. В нынешнем виде существует множество причин, по которым ваш код и логика могут дать сбой, а «странные действия» не предоставляют никаких полезных данных. Определите свои фактические данные и покажите фактические ошибки или неожиданное поведение.
Ты можешь написать
Module.const_defined?(:A) ? A : (B == true ? B : C)
чтобы получить значение A
.
A not defined
B = true
Module.const_defined?(:A) ? A : (B == true ? B : C)
#=> true
A not defined
B = false
Module.const_defined?(:A) ? A : (B == true ? B : C)
#=> 42
A = "cat"
B = false
C = 42
Module.const_defined?(:A) ? A : (B == true ? B : C)
#=> "cat"
Мы не знаем, действительно ли OP определил какую-либо из констант, поэтому любая из них может вызвать NameError. Вероятно, ему было бы лучше использовать переменные экземпляра, поскольку они автоматически оживляются.
@ToddA.Jacobs, я интерпретировал: «Только B или C будут иметь значение в любой момент времени. Иногда A будет иметь значение, а иногда нет». как означающее, что B и C были определены. Вопрос конкретно о константах - ОП может просто быть любопытным и не иметь намерения использовать код в приложении, поэтому я не задавал более широкие вопросы. Я считаю, что вопросы, вызванные любопытством, часто очень поучительны.
Я не критиковал, хотя, возможно, так оно и было. Я просто пытался отметить для других читателей и ОП, что в его вопросе отсутствуют некоторые важные детали, и ваш ответ предполагает, что и Б, и С являются defined?
, что является предположением, которое может не соответствовать реальной проблеме. В целом мне нравится ваш подход к ответам как к обучающим моментам; Я просто указывал на некоторые основные предположения в этом ответе, которые некоторые люди могут не понять интуитивно, если они не являются опытными рубистами. Я думаю, что ваш ответ хорош, но нужно проверить, что все 3 константы defined?
.
Кстати, их не нужно проверять, если все правила заявил OP действительны. Дело в том, что проблема, которую он описал, означает, что любая из его трех констант может быть вызвана в какой-то момент, поэтому, если Любые из них не определены, он, вероятно, получит NameError. Что-то вроде %w[A B C].map { Module.const_defined? _1 }.any?
не поможет, потому что даже просто A ||= B
будет повышаться, если Б не определен, поэтому С никогда не будет оцениваться, даже если он будет определен.
@CarySwoveland Спасибо за ваш отзыв. Я обновил свой вопрос. Дайте мне знать, если вы считаете, что мне нужно добавить больше информации, чтобы сделать ее более полезной для других.
@ToddA.Jacobs Спасибо за ваш отзыв. Я обновил свой вопрос. Дайте мне знать, если вы считаете, что мне нужно добавить больше информации, чтобы сделать ее более полезной для других.
Константы и локальные переменные вызовут ошибку NameError, если они не определены. Вместо этого вы, вероятно, захотите использовать переменные экземпляра, так как они автоматически оживляются как nil
при ссылке, даже если они еще не были назначены. Например:
@a ||= (@b || @c)
#=> nil
Если @а или @б верны, то, вероятно, все будет работать так, как вы ожидаете. Однако, если все три переменные ложны, то @а будет присвоено значение @с, даже если @с оценивается как nil
или false
.
@CarySwoveland Тогда @а будет ложным, а (@b || @c)
будет оцениваться методом короткого замыкания, а результат выражения будет присвоен @а. В этом случае @а все еще может оказаться ложным, в зависимости от того, что находится в @б или @с, но будем будет присвоено значение. Если вы не знаете, что находится в других переменных, трудно различить, какие значения являются nil
или false
, но согласно логике в моем ответе @а будет ложным только в том случае, если все три значения ложны, поскольку @с будет последним оцененным значением и поэтому присвоен @а.
Да, мой мозг изменил вопрос, что он делает в последнее время все чаще.
Являются ли А, В и С постоянными? Или просто заполнители для обычных переменных?