Ruby // Операторы ~ A ||= (B || C)

Есть ли способ написать с операторами следующее:

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), произошло одно из двух. Либо пользователь не сможет войти в систему, либо, если пользователь уже вошел в систему, он не сможет выйти из системы. то есть сеансы не могли быть созданы, не могли быть очищены или удалены. Именно это странное поведение я и имел в виду.

«Решение»: Тем не менее, мне удалось придумать обходной путь, подробно описанный ниже.

Обходной путь, который я нашел для своего вопроса, заключался в том, чтобы вернуться к одной пользовательской модели вместо двух. Затем добавьте в мою пользовательскую модель дополнительный столбец, в котором указан тип пользователя. Таким образом, исходный код будет работать, и я смогу контролировать свой пользовательский интерфейс на основе этого «столбца управления».

Являются ли А, В и С постоянными? Или просто заполнители для обычных переменных?

spickermann 09.04.2022 07:58

Вы должны включить фактические данные в свой вопрос. В нынешнем виде существует множество причин, по которым ваш код и логика могут дать сбой, а «странные действия» не предоставляют никаких полезных данных. Определите свои фактические данные и покажите фактические ошибки или неожиданное поведение.

Todd A. Jacobs 09.04.2022 08:12
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
2
36
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Ты можешь написать

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"

См. Модуль № const_defined?.

Мы не знаем, действительно ли OP определил какую-либо из констант, поэтому любая из них может вызвать NameError. Вероятно, ему было бы лучше использовать переменные экземпляра, поскольку они автоматически оживляются.

Todd A. Jacobs 09.04.2022 08:15

@ToddA.Jacobs, я интерпретировал: «Только B или C будут иметь значение в любой момент времени. Иногда A будет иметь значение, а иногда нет». как означающее, что B и C были определены. Вопрос конкретно о константах - ОП может просто быть любопытным и не иметь намерения использовать код в приложении, поэтому я не задавал более широкие вопросы. Я считаю, что вопросы, вызванные любопытством, часто очень поучительны.

Cary Swoveland 09.04.2022 10:50

Я не критиковал, хотя, возможно, так оно и было. Я просто пытался отметить для других читателей и ОП, что в его вопросе отсутствуют некоторые важные детали, и ваш ответ предполагает, что и Б, и С являются defined?, что является предположением, которое может не соответствовать реальной проблеме. В целом мне нравится ваш подход к ответам как к обучающим моментам; Я просто указывал на некоторые основные предположения в этом ответе, которые некоторые люди могут не понять интуитивно, если они не являются опытными рубистами. Я думаю, что ваш ответ хорош, но нужно проверить, что все 3 константы defined?.

Todd A. Jacobs 09.04.2022 18:40

Кстати, их не нужно проверять, если все правила заявил OP действительны. Дело в том, что проблема, которую он описал, означает, что любая из его трех констант может быть вызвана в какой-то момент, поэтому, если Любые из них не определены, он, вероятно, получит NameError. Что-то вроде %w[A B C].map { Module.const_defined? _1 }.any? не поможет, потому что даже просто A ||= B будет повышаться, если Б не определен, поэтому С никогда не будет оцениваться, даже если он будет определен.

Todd A. Jacobs 09.04.2022 18:53

@CarySwoveland Спасибо за ваш отзыв. Я обновил свой вопрос. Дайте мне знать, если вы считаете, что мне нужно добавить больше информации, чтобы сделать ее более полезной для других.

Marc Auciello 09.04.2022 23:07

@ToddA.Jacobs Спасибо за ваш отзыв. Я обновил свой вопрос. Дайте мне знать, если вы считаете, что мне нужно добавить больше информации, чтобы сделать ее более полезной для других.

Marc Auciello 09.04.2022 23:07

Константы и локальные переменные вызовут ошибку NameError, если они не определены. Вместо этого вы, вероятно, захотите использовать переменные экземпляра, так как они автоматически оживляются как nil при ссылке, даже если они еще не были назначены. Например:

@a ||= (@b || @c)
#=> nil

Если или верны, то, вероятно, все будет работать так, как вы ожидаете. Однако, если все три переменные ложны, то будет присвоено значение , даже если оценивается как nil или false.

@CarySwoveland Тогда будет ложным, а (@b || @c) будет оцениваться методом короткого замыкания, а результат выражения будет присвоен . В этом случае все еще может оказаться ложным, в зависимости от того, что находится в или , но будем будет присвоено значение. Если вы не знаете, что находится в других переменных, трудно различить, какие значения являются nil или false, но согласно логике в моем ответе будет ложным только в том случае, если все три значения ложны, поскольку будет последним оцененным значением и поэтому присвоен .

Todd A. Jacobs 09.04.2022 18:36

Да, мой мозг изменил вопрос, что он делает в последнее время все чаще.

Cary Swoveland 09.04.2022 20:35

Другие вопросы по теме