Ruby Syntax Explanation [duplicate] - ruby

This question already has answers here:
How does this block work for Integer times method?
(2 answers)
Closed 6 years ago.
I was reading through the documentation for Enumerator and I ran across this example:
fib = Enumerator.new do |y|
a = b = 1
loop do
y << a
a, b = b, a + b
end
end
Everything makes sense to me except for this line: a, b = b, a + b. Could somebody please explain what's happening?

It's a parallel assignment pattern which you can see in many languages including ruby
probably you will find this helpful
Parallel Assignment operator in Ruby

Related

Division with if condition [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I just start learning ruby with an online course and in my very first exercise, I can't complete the challenge. I have to create functions to sum, subtract, multiply and divide that meet the specs conditions.
For the division, I need to check if it will divide per 0 or not, give the result or a warning. My code is
def divisao(primeiro_numero, segundo_numero)
if segundo_numero > 0
primeiro_numero / segundo_numero
else
puts 'Opa! Zero como divisor'
end
But when I run the specs, I get the following warning
0 examples, 0 failures, 1 error occurred outside of examples
I have changed all the functions, but this one doesn't seem to work.
I added the complete functions and specs file here:https://gist.github.com/isafloriano/86c170400b2f5fc63dc5e8edd8913525
Can anyone give me a clue why this doesn't work?
You are just missing the end of the if-else block:
def divisao(primeiro_numero, segundo_numero)
if segundo_numero > 0
primeiro_numero / segundo_numero
else
puts 'Opa! Zero como divisor'
end # <= this one was missing
end
Some suggestion:
Use English method and variable names. That makes it easier for others to understand your code and to help you.
Try to follow common Ruby conventions right from the start. Ruby code is indented with two spaces.
Here's a compact way to write your four methods.
def add(n1, n2)
f(n1, n2, :+)
end
def subtract(n1, n2)
f(n1, n2, :-)
end
def multiply(n1, n2)
f(n1, n2, :*)
end
def divide(n1, n2)
if n2.zero?
puts "Zero-divide error"
return nil
end
f(n1, n2, :/)
end
def f(n1, n2, op)
n1.public_send(op, n2)
end
add(3, 7) #=> 10
add(5, 7.2) #=> 12.2
subtract(4, 8) #=> -4
subtract(6.1, 3) #=> 3.0999999999999996
multiply(2, 6) #=> 12
multiply(1.0, 6) #=> 6.0
divide(4, 0) #=> nil
Zero-divide error
divide(4, 0.0) #=> nil
Zero-divide error
divide(4, 2) #=> 2
divide(5, 2) #=> 2
divide(5, 2.0) #=> 2.5
See Object#public_send.

How is line 2 is evaluated? [duplicate]

This question already has answers here:
What is x after "x = x++"?
(18 answers)
Why is this Java operator precedence being ignored here?
(7 answers)
Closed 4 years ago.
int f = 1;
f = f++;
System.out.println(f);
post increment operator is having a higher precedence than assignment operator so
i suppose value of f (that is 1) is used for assignment and f is incremented then the output would be 2 (as value of f is now 2)
but the output is 1, but how? where am i wrong?
my explanation results in right answer in the code below
int f = 1;
int g = f++;
System.out.println(f);
output is 2 in this case.
You can't assign a value to a variable before you evaluate the value. Hence you must evaluate f++ first. And since f++ returns 1, that's the value assigned to f, which overwrites the incremented value of f.
Your second snippet is a completely different scenario, since you assign the value of f++ to a different variable, so the incremented value of f is not overwritten.

What's the proper way to use the <=> operator in Ruby? [duplicate]

This question already has answers here:
What is the Ruby <=> (spaceship) operator?
(6 answers)
Closed 4 years ago.
I don't quite understand how this works. I guess a large part of it is because I'm used to C and its low-level data structures, and programming at a higher level of abstraction takes some getting used to. Anyway, I was reading The Ruby Programming Language, and I came to the section about ranges and how you can use the <=> operator as sort of a shorthand for what in C you would have to implement as a sequence of if-else statements. It returns either -1, 0, or 1 depending on the results of the comparison. I decided to try it out with the following statement:
range = 1..100
r = (100 <=> range)
print( r )
The result is an empty string. So my question is, how does this operator work; what data type does it return (I assume the return value is an integer type but I can't say for sure); and finally what is the proper way to use it? Thanks for your time, and sorry if this was already answered (I didn't see it in the listing).
The <=> operator is meant to compare two values that can be compared directly, as in strings to strings or numbers to numbers. It can't magically compare two different things, Ruby doesn't convert for you like that.
As such you need to use it in the right context:
1 <=> 2
# => -1
2 <=> 1
# => 1
1 <=> 1
# => 0
When the two things can't be compared you get nil. Note that this is different from "empty string":
1 <=> '1'
# => nil
That means "invalid comparison". The <=> operator is being nice here because in other situations you get an exception:
1 < '1'
# => ArgumentError: comparison of Integer with String failed
You can also use this operator to make your own Comparable compatible class:
class Ordered
include Comparable
attr_reader :sequence
def initialize(sequence)
#sequence = sequence
end
def <=>(other)
self.sequence <=> other.sequence
end
end
Then you can do this:
a = Ordered.new(10)
b = Ordered.new(2)
[ a, b ].sort
# => [#<Ordered:0x00007ff1c6822b60 #sequence=2>, #<Ordered:0x00007ff1c6822b88 #sequence=10>]
Where those come out in order. The <=> implementation handles how these are sorted, and you can finesse that depending on how complex your sorting rules are.
Using the return values -1, 0, and 1 only as labels describing different states, you can write a condition that depends on the order between two numbers:
case a <=> b
when -1 then # a is smaller than b. Do something accordingly
when 0 then # a equals b. Do something accordingly
when 1 then # a is larger than b. Do something accordingly
end
Or, a use case where you can make use of the values -1, 0, and 1, is when you want to get the (non-negative) difference between two numbers a and b without using the abs method. The following:
(a - b) * (a <=> b)
will give the difference.
Add to the other answers this snippet: The "spaceship operator" returns -1, 0, or 1 so you can use it when comparing items in a .sort call:
events.sort {|x, y| y.event_datetime <=> x.event_datetime}
0 means the two items are the same, 1 means they are different but in the correct sort order, and -1 means they are out of order. The above example reverses x and y to sort into descending order.
In C, the function strcmp() has roughly the same behavior, to fit with qsort(), with the same semantics.

what makes an operator <=> in the block min? [duplicate]

This question already has answers here:
What is the Ruby <=> (spaceship) operator?
(6 answers)
Closed 6 years ago.
Have following example of code:
%w{ Ruby C APL Perl Smalltalk}.min {|a,b| a.size <=> b.size}
return "C"
Can you explain me why "C"? What makes an operator "<=>" ?
The Spaceship operator returns -1 if the left is less than the right, 0 if they are equal, and 1 if the left is greater than the right.
In this case, you're comparing the length of each word in the array and returning the shortest word. If you removed .size from the variable in the block, it would instead return the first word that occurs alphabetically (i.e. 'APL').
What is the Ruby <=> (spaceship) operator?

Why doesn't this algorithm yield the fibonacci sequence under 100? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
a = 1; b = 2
fibonacci = []
while fibonacci.length < 100
fibonacci.push(a)
fibonacci.push(b)
a = a + b; b = a + b
end
push fibonacci
The error message is "undefined method `push' for main:Obj"
You're trying to #push the array itself on the last line! :)
That's what it's complaining about. The push method is being invoked on the 'main' object, and push is not a Kernel method.
I'm guessing you mean puts. Otherwise it looks okay, if somewhat non-idiomatic. Naturally you can find lots of Ruby solutions for this problem on the site that might read a bit more clearly (see here for a recursive one.)
As others have said before the last line should be 'puts'
Also your numbers are wrong.
a = 1; b = 1
fibonacci = []
while fibonacci.length < 100
fibonacci << a
fibonacci << b
a += b
b += a
end
puts fibonacci
But also the fib starts at 1 and the the second element is also 1.
This make you sequence off, if you start at 1, 2
Fib = 1, 1, 2, 3, 5, 8, ...

Resources