1

Just tripped over an instruction that is unclear:

a = 5 || 3                       # ==> 5
verdict = true || false          # ==> true

Since || is the same as or, how and/or why would this statement be used? It doesn't really demonstrate any decision making other than choosing the first option always.

I know the ||= assignment, but this is different. Looking for clarification on the usage above of || alone.

Rich_F
  • 1,830
  • 3
  • 24
  • 45
  • 4
    `number = options[:number] || 42` – Aleksei Matiushkin Oct 25 '19 at 08:03
  • 1
    Where did you stumble on this example? Used like this it does not make any sense. – Denny Mueller Oct 25 '19 at 08:03
  • @DennyMueller If you are asking me (not clear), I saw it in a video yesterday, don't have url. It doesn't make sense, but it takes on meaning if it becomes boolean. – Rich_F Oct 25 '19 at 08:08
  • @AlekseiMatiushkin That hasn't explained anything, just repeated the question in another example. – Rich_F Oct 25 '19 at 08:08
  • 1
    @Rich_F the example of @AlekseiMatiushkin actually makes more sense since `options[:number]` could be `nil` and with `number = options[:number] || 42` you make sure either the number in the `options` hash is assigned or `42` . `nil || 42 #=> 42`. – Denny Mueller Oct 25 '19 at 08:10
  • @DennyMueller OK, that's a `conditional` then. That comes back to the `boolean` sense in that if the first value defaults, then second value becomes the value. Can I assume first value takes preference? – Rich_F Oct 25 '19 at 08:13
  • 1
    yes that's correct its more like a `if true; else; ` – Denny Mueller Oct 25 '19 at 08:26
  • @DennyMueller Good to know. Learned something. – Rich_F Oct 25 '19 at 08:31
  • 4
    @Rich_F [Difference between `or` and `||`](https://stackoverflow.com/questions/2083112/difference-between-or-and-in-ruby) – Viktor Oct 25 '19 at 08:46

1 Answers1

2
a = b || c

What this statement does is, it tells Ruby to 'assign the value of b to a, unless b is falsy, if b is falsy, assign the value of c to a. In case b isn't falsy, the c statement won't get executed.

A good example where you could use this is if you're getting a variable from somewhere and you're not sure if it's going to be nil or not, so you create a variable like c as a second option.

If you have a method that takes in a hash as a parameter for example, and you want to return the value of the element from the hash that has the key 'b' for example, but the hash parameter won't always have a 'b' key, so you write something like this

def value_of_b(hash)
  b_val = hash['b'] || 'unknown'
  puts "The value of b is :#{b_val}"
end

h = {'a' => 1, 'b' => 2}

value_of_b(h)
#=>The value of b is :2

m = {'a' => 1}

value_of_b(m)
#=>The value of b is :unknown

Another example that comes to my mind is accessing an array element that doesn't exist

[1,2,3][3] || "default"
#=> "default"

Or having a default value for Rails params hash:

@name = params[:name] || "no name provided"
Viktor
  • 2,623
  • 3
  • 19
  • 28
  • OK, so precedence. I've not tripped over that term **falsey**. For something like this I usually turn to a `ternary`. Your `array` example probably shows it best. It has a built-in conditional. – Rich_F Oct 25 '19 at 08:56
  • 1
    Sorry, it's falsy. It was a typo. [Falsy](https://riptutorial.com/ruby/example/2092/truthy-and-falsy-values) is usually the term used to describe a variable that is either `nil` or `false` – Viktor Oct 25 '19 at 09:00
  • 1
    @Viktor _falsey_ (or _falsy_) is used to describe a variable that is treated as `false` in boolean expressions. In different languages it might include more (like `0` or `""` in [tag:php].) – Aleksei Matiushkin Oct 25 '19 at 09:07
  • @AlekseiMatiushkin Ya that's what Viktor was indicating. So the conditional is on the first value, second value being the default. I've not run across this. – Rich_F Oct 25 '19 at 09:08
  • Not necessarily. If one has `local_defaults` and `global_defaults`, and `args` passed from the outside, it might take a form `args[:param] || local_defaults[:param] || global_defaults[:param]`. Ot, think about blog entry in the database `post[:title] || post[:excerpt] || post[:body][0..63]`. – Aleksei Matiushkin Oct 25 '19 at 09:11
  • 2
    It might be worth noting that `||` is a _short-circuit operator_, i.e. the right-hand side is evaluated only if the left-hand side is falsey. – Stefan Oct 25 '19 at 10:21
  • @CarySwoveland You're right, it doesn't add any value to the answer. Thank you – Viktor Oct 25 '19 at 14:45
  • You can also do cool stuff like foo = condition && value_if_condition_true || value_if_condition_false – Dennis Oct 25 '19 at 17:31