Assigning from conditionals
In Ruby, since conditionals are expressions, you can assign their result to a variable:
User = Struct.new(:admin, :moderator) do
def admin? = admin
def moderator? = moderator
end
user = User.new(admin: false, moderator: true)
status =
if user.admin?
"admin"
elsif user.moderator?
"moderator"
else
"user"
end
# => "moderator"
class User {
constructor({ admin, moderator }) {
this.admin = admin;
this.moderator = moderator;
}
isAdmin() {
return this.admin;
}
isModerator() {
return this.moderator;
}
}
const user = new User({ admin: false, moderator: true });
let status;
if (user.isAdmin()) {
status = "admin";
} else if (user.isModerator()) {
status = "moderator";
} else {
status = "user";
}
// => "moderator"
This also works with case expressions:
User = Class.new
Admin = Class.new(User)
Moderator = Class.new(User)
user = Admin.new
status =
case user
when Admin
"admin"
when Moderator
"moderator"
else
"user"
end
# => "admin"
class User {}
class Admin extends User {}
class Moderator extends User {}
const user = new Admin();
let status;
if (user instanceof Admin) {
status = "admin";
} else if (user instanceof Moderator) {
status = "moderator";
} else {
status = "user";
}
// => "admin"
As you can see, this can significantly reduce the amount of repetition in the code, making it more concise and to the point.
Disclaimer: The last example is contrived, but serves to illustrate the point. We could just as well have used status = user.class.name.downcase to get the same result
History
Conditionals have always been expressions in Ruby. The idea for this is likely inspired by Lisp, where everything is an expression. Smalltalk also allows assigning from conditionals in a sense, since in Smalltalk everything is a message send and messages return values.
After Ruby, quite a few modern languages have picked up the idea of conditionals being expressions, such as Rust, Elixir and Kotlin.