Conditional Assignment: ||= and the Boolean Operator Tricks
Ruby's||= is the Perl refugee's //=. Assign a default value only if the variable is nil or false. Combined with &&= and the fact that || and && return actual values (not just true/false), you get a powerful set of tools for defensive coding. But there's a gotcha with false that'll bite you if you're not careful.
Part 1: ||= (Assign if nil/false)
Perl equivalent:count ||= 0 # assign only if count is nil or false name ||= "anonymous" # set default hash[:key] ||= [] # autovivify! create array if missing
$count //= 0; (defined-or-assign, Perl 5.10+)
Important difference: Perl's //= checks for defined. Ruby's ||= checks for truthiness (nil OR false). In Ruby, 0 and "" are truthy, so ||= won't overwrite them. In Perl, //= won't overwrite 0 or "" either (they're defined). So in practice, they behave similarly for most cases.
Part 2: &&= (Assign if truthy)
Perl:string &&= string + " suffix" # Only modifies string if it's not nil/false # Equivalent to: # if string # string = string + " suffix" # end name &&= name.strip # strip only if name exists
$string &&= $string . " suffix"; (works the same).
Part 3: Boolean Operators Return Values
This is identical to Perl.&& and || return the actual value, not just true/false.
|| returns first truthy value
Perl:name = params[:name] || ENV['USER'] || "anonymous" # Checks each, returns the first one that isn't nil/false port = config[:port] || 8080 # Use config port, fall back to 8080
my $name = $params{name} || $ENV{USER} || "anonymous";
&& returns first falsy, or last truthy
result = valid? && process_data && save_result # Short-circuits on first false/nil # Returns the actual false/nil value, or the last truthy value # Practical: conditional chaining line && line.strip && line.strip.length > 0
Part 4: Default Value Patterns
# Simple default timeout = options[:timeout] || 30 # Nested default with ||= config[:database] ||= {} config[:database][:host] ||= "localhost" config[:database][:port] ||= 5432 # From environment with fallback db_host = ENV['DB_HOST'] || "localhost" db_port = (ENV['DB_PORT'] || 5432).to_i
Part 5: The false Gotcha
This is the one place where Ruby's# DANGER: ||= treats false as "not set" flag = false flag ||= true # flag is now true! Probably not what you wanted. # If you need to handle false vs nil: flag = true if flag.nil? # only overwrites nil, not false
||= and Perl's //= diverge in practice. Perl's //= won't overwrite false because false is defined. Ruby's ||= will, because false is falsy.
Part 6: Comparison with Perl
| Pattern | Perl | Ruby |
|---|---|---|
| Default value | $x || "default" |
x || "default" |
| Defined-or | $x // "default" |
No exact equivalent; use x.nil? ? "default" : x |
| Assign if undef | $x //= "default" |
x ||= "default" (but catches false too) |
| Short-circuit AND | valid() && process() |
valid? && process |
| Short-circuit OR | try_a() || try_b() |
try_a || try_b |
Created By: Wildcard Wizard. Copyright 2026