1

Are you able to assign strings to true and false?

for example I'm starting with a hash:

shopping_list = {
  "milk" => false,
  "eggs" => false,
  "jalapenos" => true
}

puts "Here is your Shopping List:"

shopping_list.each do |key, value|
  puts "#{key} - #{value}"
end

I was wanting the output to puts "purchased" for true and "not purchased" for false.

Stefan
  • 109,145
  • 14
  • 143
  • 218
realfauxreal
  • 113
  • 7

3 Answers3

3

Does this answersed your question?

shopping_list.each do |key, value|
   puts "#{key} - #{purchased?(value)}"
end


def purchased?(boolean)
  boolean ? 'purchased' : 'not purchased' 
end
spike 王建
  • 1,556
  • 5
  • 14
  • ohhh thank you. I haven't learned about boolean yet. This is very cool. Thank you so much for your time. – realfauxreal Sep 02 '20 at 16:42
  • @realfauxreal - Welcome to SO. Please do accept anwer as accepted if they help you solve the problem. – Alok Swain Sep 02 '20 at 16:50
  • 1
    I am not a big fan of the conditional operator in Ruby. The conditional operator is required in C, because in C, the conditional statement is, well, a *statement*, and the conditional operator is an *expression*. But Ruby doesn't have statements anyway, so the conditional expression is already an expression. There is no need for the conditional operator to even exist, it is opaque, hard to read, and has non-intuitive precedence. I very much prefer the conditional expression, e.g. in your case `if boolean then 'purchased' else 'not purchased' end` – Jörg W Mittag Sep 03 '20 at 06:49
  • @JörgWMittag Thanks for your comment, maybe conditional expression is more rubyist's or not.But conditional operator also worked and no side effect somehow.And in my opinion, it is shorter and more directly. – spike 王建 Sep 03 '20 at 07:04
2

Use an inline if or a ternary if operator:

shopping_list = {
  "milk" => false,
  "eggs" => false,
  "jalapenos" => true
}

puts "Here is your Shopping List:"

shopping_list.each do |key, value|
  puts "#{key} - #{if value then 'purchased' else 'not purchased' end}"
  # or this:
  # puts "#{key} - #{value ? 'purchased' : 'not purchased'}"
end

Prints:

Here is your Shopping List:
milk - not purchased
eggs - not purchased
jalapenos - purchased

Which operator to use: ternary operator (?:) or if/then/else/end?

I chose here if/then/else/end, but listed both options as acceptable. It is a matter of style which one you choose.

Some Stack Overflow Ruby users prefer to use a regular if ... then ... else ... end. It is longer, but more clear and more idiomatic. See, for example, these answers:
https://stackoverflow.com/a/2175392/967621
https://stackoverflow.com/a/4253250/967621

Other Stack Overflow users prefer ?:, which is more concise and clear, if you are used to it. Also note that The Ruby Style Guide agrees:

Prefer the ternary operator(?:) over if/then/else/end constructs. It’s more common and obviously more concise.

# bad
result = if some_condition then something else something_else end

# good
result = some_condition ? something : something_else
Timur Shtatland
  • 12,024
  • 2
  • 30
  • 47
  • Thank you so much. I think I would have had a hard time discovering this at my level on my own. – realfauxreal Sep 02 '20 at 16:43
  • 2
    I am not a big fan of the conditional operator in Ruby. The conditional operator is required in C, because in C, the conditional statement is, well, a *statement*, and the conditional operator is an *expression*. But Ruby doesn't have statements anyway, so the conditional expression is already an expression. There is no need for the conditional operator to even exist, it is opaque, hard to read, and has non-intuitive precedence. I very much prefer the conditional expression, e.g. in your case `puts "#{key} - #{if value then 'purchased' else 'not purchased' end}"` – Jörg W Mittag Sep 03 '20 at 06:48
  • @JörgWMittag Thank you for the suggestion on improving the code by using the `if/then/else/end` instead of the `?:`. – Timur Shtatland Sep 03 '20 at 22:55
  • _"The consensus of Stack Overflow Ruby users is ..."_ – I somehow missed that poll, where can I vote? ;-) – Stefan Sep 04 '20 at 11:24
  • @Stefan Good point, thank you! I found no poll either. :) The closest I found were these 2 questions, which address the issue indirectly: https://stackoverflow.com/q/2174419/967621 , https://stackoverflow.com/q/4252936/967621 . I referred to 2 relevant answers above. I inferred the consensus **indirectly** from these threads. Maybe I should mention this explicitly in my answer. I guess that the question like "When should I used `if/then/else/end` vs `?:`" would be closed on SO as opinion-based. But I could be wrong - maybe it is worth to try and post this Q to get a few more good answers? – Timur Shtatland Sep 04 '20 at 15:06
  • It's probably a matter of coding style or what you're used to. I'd argue that `foo ? bar : baz` – despite being more cryptic – is easier to recognize. To me, `if foo then bar else baz end` looks like a run-on sentence and I need much longer to grasp what's going on. But again, that's purely objective. Your mileage may vary :-) – Stefan Sep 04 '20 at 15:29
  • @Stefan Thank you for your comment! I improved the reasoning behind the 2 different coding styles here. – Timur Shtatland Sep 04 '20 at 15:39
2

I was wanting the output to puts "purchased" for true and "not purchased" for false.

You'd typically start with an if expression:

shopping_list.each do |key, value|
  if value
    puts "#{key} - purchased"
  else
    puts "#{key} - not purchased"
  end
end

Later on, you can try to remove the duplicate code parts.


Are you able to assign strings to true and false?

That sounds like a mapping. You can use another hash:

states = {
  true => 'purchased',
  false => 'not purchased'
}

And refer to that hash when printing your shopping list:

shopping_list.each do |key, value|
  puts "#{key} - #{states[value]}"
end

Here, states[value] fetches the output value for value from the states hash.

Stefan
  • 109,145
  • 14
  • 143
  • 218