What does "!" symbol mean in Ruby language [duplicate] - ruby

This question already has answers here:
Exclamation points before a variable in Ruby
(3 answers)
Closed 2 years ago.
For example: what is this saying:
if !result[movie[:studio]]
result[movie[:studio]] = movie[:worldwide_gross]
else
result[movie[:studio]] += movie[:worldwide_gross]
end
i += 1
end
This is a solution to manipulating an NDS, or rather getting some information from an NDS and I can't seem to find what the !result means.

The ! negates the element. So if result[movie[:studio]] is truthy then !result[movie[:studio]] is the opposite, falsy. Your conditional statement is basically saying that if there is no value for the studio key then give it a value of movie[:worldwide_gross], otherwise add to the current value.
If you do not like the ! you could consider using unless instead or swap the order of the conditional.
if result[movie[:studio]]
result[movie[:studio]] += movie[:worldwide_gross]
else
result[movie[:studio]] = movie[:worldwide_gross]
end

! negates the element as it was already mentioned.
So, !true => false
So if you do
if !hungry
do x
end
You will execute X if you are not hungry.
It might also be used on null. So you can use it to check if "not null". This might be the use case that you're seeing.

Related

Ruby, `puts` doesn't print anything [duplicate]

This question already has answers here:
Why does Ruby's 'gets' includes the closing newline?
(5 answers)
Closed 2 years ago.
I'm new to writing in Ruby and I have this assignment for my Programming Languages class where I have to implement Mergesort into Ruby such that the user can enter an array of their own choice of numbers and end with a -1. I thought I had everything written in correctly, there are no bugs being reported, but the program doesn't print anything out.
Here's the important part of the code:
puts "Please enter as many numbers as you would like followed by -1"
Many_Numbers = Array.new
x_1 = '-1'
while gets != x_1
Many_Numbers.push gets
end
sorted = merge_sort(Many_Numbers)
puts "SORTED CORRECTLY: #{sorted == Many_Numbers.sort}\n\n#{Many_Numbers}\n\n#{sorted}"
Like I said, nothing is printed out, not even what is provided in the puts methods, so I have nothing to present for an error. What am I doing wrong, here?
EDIT:
I edited the code after I had an idea to improve this part of the code but I still got nothing.
This is what I changed
puts "Please enter as many numbers as you would like followed by -1"
Many_Numbers = Array.new
input = gets
while input != -1
case response
when input != -1
Many_Numbers.push(input)
when input == -1
end
end
You have a couple of problems with your input code.
gets returns all the user input, which includes the newline. So, your loop condition is comparing "-1" to "-1\n" and hence will never end. Calling .chomp on the input will fix that.
You are calling gets twice for each valid number -- once in the loop condition and once when you actually push a value into your array. This causes the loss of one of every two entries. Using a loop do construct with a break condition can fix that problem.
END_OF_LIST = '-1'
puts "Please enter as many numbers as you would like followed by -1"
Many_Numbers = Array.new
loop do
val = gets.chomp
break if val == END_LIST
Many_Numbers.push val
end
The good news is your merge sort method appears to be working once you sort out your input woes.

Why does `defined?` keyword not return boolean? [duplicate]

This question already has answers here:
Why does `defined?` return a string or nil?
(2 answers)
Closed 7 years ago.
In ruby, most methods or keywords that end with ? return boolean values. And we except them to behave like this. Why does defined? keyword return somethings else? Or why is there ? at the end of it?
This question can be understood in two ways:
Why doesn't it simply return true or false?
It's because it encodes more information than simply if something is defined or not:
defined? Class # => "constant"
defined? 42 # => "expression"
defined? nil # => "nil"
defined? x # => nil
Why does it have ? at the end since as the convention goes, the question mark is reserved for predicates?
You are right that this is inconsistent. The most likely reasons are:
Almost always, you will use it as predicate anyway
if defined? x
# do something
end
The shortest alternative, which doesn't sound like a predicate I can think of is definition_type_of. Generally, you want to keep the reserved words in your language short
Developers chose to return something more meaningfull than true or false because the only case that breaks by not having boolean returned is explicit comparison:
defined?(:x) == true
# => always `false`
Such comparison is something you should usually not do, as logical operators like || and && are just as likely to return some truthy object instead of true. This is barely needed for anything.
The "defined?"-method can return more than "true" or "false". It tells you what type of variable it is if it's defined at all.
Check
Checking if a variable is defined?
and
http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-defined-3F

What does "||=" mean in Ruby? [duplicate]

This question already has answers here:
What does ||= (or-equals) mean in Ruby?
(23 answers)
Closed 7 years ago.
I'm still pretty green when it comes to Ruby and am trying to figure out what this is doing:
command_windows.each {|window| window.hidden ||= window.open? }
The command_windows variable appears to be an array of objects. If someone could explain to me what this line of code means, particularly what the ||= symbol is I would appreciate it.
foo ||= "bar" is the equivalent of doing foo || foo = "bar".
As Mischa explained, it checks for a falsy value before assigning.
In your case, you could think of it as:
command_windows.each {|window| window.hidden || window.hidden = window.open? }
which is another way of saying
command_windows.each {|window| window.hidden = window.open? unless window.hidden }
The ||= operator is used to assign new value to variable. If something was assigned to it before it won't work. It is usually used in hashes, so you don't have to check, if something is already assigned.

next and previous for letters and symbols array [duplicate]

This question already has an answer here:
What is the opposite of string.next?
(1 answer)
Closed 9 years ago.
Because
"A".next => "B"
and
"#".next => "$"
How would I find the previous item? So that:
"$".previous => "#"
If you only need it to work on single character strings, you could extend String:
class String
def previous
return (self.ord - 1).chr
end
end
Then:
"$".previous # => "#"
I'm not a big ruby programmer, so I don't know how bad of a practice this is, but it does work if you need it.
Here's one way to do it for individual characters:
('B'.ord-1).chr # => 'A'
('$'.ord-1).chr # => '#'
From What is the opposite of string.next?
prev or something similar is not in the standard API because succ and a hypoethetical prev are surjective. Despite this, "Implement Ruby String Class Prev / Pred / Prev! / Pred! - Opposite Of Next / Succ Methods" is a possible version you could use.
The root problem is that succ is not inversible. This means, once you applied succ, then prev would end up with some ambiguity.
Credits to Bjoern Rennhak.

Why the value of the assignment is always the value of the parameter? [duplicate]

This question already has an answer here:
Why isn't `method=` treated the same as any other method?
(1 answer)
Closed 6 years ago.
Would someone care to explain why in older versions of Ruby, the result of the assignment was the value returned by the attribute-setting method, but after Ruby 1.8, the value of the assignment is always the value of the parameter; the return value of the method is discarded. In the code that follows, older versions of Ruby would set result to 99. Now result will be set to 2.
class Test
def val=(val)
#val = val
return 99
end
end
t = Test.new
result = (t.val = 2)
result # => 2
What was the reasoning behind this change?
It's not uncommon to chain assignments together when you want to assign the same value to multiple variables. This is even more common in other languages.
#user_id = user.id = next_user_id
But what happens when you aren't thinking about that, and so the return value isn't the same as the input value?
class User
def id=(name)
#id = name
#modified = true
end
def modified?
#modified
end
end
This code will work totally fine until one day when you go drop it in an assignment chain like the above, when all of a sudden you'll get unexpected results.
So, the interpreter does some sort of voodoo and ensures that the RHS of the assignment is the return value, discarding the actual return value.
Assignments always evaluate to the assigned value. That's a simple and consistent rule, both consistent within Ruby itself, as well as consistent with most other expression-based programming languages.
Everything else would be an inconsistent special case, and those are bad.

Resources