What does this operator #{var} do in ruby? [duplicate] - ruby

This question already has answers here:
Ruby question about # Signs
(2 answers)
Closed 7 years ago.
This is from a coderbyte solution to a problem that asks you to look at two integers and determine if there is any digit that occurs three times consecutively in the first number and twice consecutively in the second number. A user posted this solution (partial below), and I understand intuitively what their code is doing, but I'm not sure exactly how these #{i}'s work or what that operator is even called. Looking for more info.
It makes sense to me that you couldn't just say:
string.include?(iii) because that's just silly.
But what is the #{} doing exactly?
arr = num1.to_s.split("").uniq
arr.each do |i|
if num1.to_s.include?("#{i}#{i}#{i}") && num2.to_s.include?("#{i}#{i}")
return 1
end
end

The #{} allows you to execute ruby code within a string. For example,
puts "two plus two is #{2+2}. will give out the output "two plus two is 4." Be careful though, #{} will only work between double quotes and will not work between single quotes. In your example the #{i} will evaluate to the var i from arr.each do |i|

It's the string interpolation syntax: https://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Literals#Interpolation

Related

What does the `&:symb` do? [duplicate]

This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 4 years ago.
I've seen an example of how to sort a string. To sort case insensitively:
str.chars.sort(&:casecmp).join
#=> "ginrSt"
I'm curious about (&:casecmp). I found that for example:
arr.map(&:name)
is shorthand for
arr.map(&:name.to_proc)
which is same with
arr.map{|el| el.name}
I know the & (ampersand) tries to convert symbol to proc, and pass it as a block to a method. I do not understand how this would work for sort method, which is supposed to compare two values. Would it be as follows?
str.chars.sort{|a, b| a.casecmp ;b.casecmp}.join
It wouldn't be helpful since soft needs a block to return an integer and casecmp needs an argument. (Or is it called parameter in that case?) To me, it looks more like this:
str.chars.sort{|a, b| a.casecmp(b)}.join
How does &:casecmp know to take one of |a, b| as a caller and the other one as an argument? I wouldn't guess it that it is an option.
If more than one parameter is passed to your block, the proc created by Symbol#to_proc uses the additional block parameters as parameters to the method call.
http://phrogz.net/symbol-to-proc-with-multiple-arguments
So, what's really happening is, sort(&:casecmp) is converted to:
sort {|a,b| a.casecmp(b) }
because sort takes two parameters.

Ruby lexical scope inside iterator block [duplicate]

This question already has answers here:
Why can I refer to a variable outside of an if/unless/case statement that never ran?
(3 answers)
Closed 5 years ago.
In Ruby (v2.5.0)...
[1,2,3].map do |i|
if i.eql?(3)
a = 123
end
defined?(a)
end
=> ["local-variable", "local-variable", "local-variable"]
Can someone please explain to me how a can be a local-variable (equal to nil) in the first and second iteration, if it's not set until the third iteration?
Thanks in advance!
I will answer quoting a book by A.Black: Well Grounded Rubyist, Chapter 6, p. 158. (second edition 2014):
When the Ruby parser sees the sequence identifier, equal-sign, and value, as in this expression,
a = 123
it allocates space for a local variable a. The creation of the variable - not the assignment of a value to it, but the internal creation of a variable - always takes place as a result of this kind of expression, event if the code isn't executed.

Use 'puts' with block accepting method over multiple lines [duplicate]

This question already has answers here:
Ruby Print Inject Do Syntax
(3 answers)
Closed 7 years ago.
Let's say I have the following (working) pseudo-code:
puts results.fields.inject('') { |string, key|
lengths[key] = calculate_length(key)
string << format(key)
}
Following the ruby-style-guide I should
Omit parentheses for 'keyword methods', i.e. puts, (which would create }) or end) anyway)
Use do...end for multi-line blocks
However, when replacing {...} with do...end it raises
undefined method `' for :title:Symbol (NoMethodError)
Therefore, is it possible to refactor this code without violenting the guideline?
There is a difference in precedence between {} and do end
If you use do end the block is associated with the puts statement, whereas the braces are associated with the results.field.inject('')
If you want to use do end then you have to remove the ambiguity of association by parentheses. It's one of those "gotchas" where the guidelines are recognized as guidelines, not absolute rules.
See also this answer...
In Ruby, why is a method invocation not able to be treated as a unit when "do" and "end" is used?

How would make this more elegant [duplicate]

This question already has an answer here:
How can I more elegantly remove duplicate items across all elements of a Ruby Array?
(1 answer)
Closed 8 years ago.
I have this piece of code in an application and was told to make it more elegant but have no idea how to make it better
self.join(" ").split(" ").uniq
Any suggestion will be much appreciated.
self is an array
flat_map(&:split).uniq
flat_map runs a block over an array, and concatenates all the resulting arrays.
flat_map(&:split) is equivalent to calling s.split on every argument, which happens to do the exact same thing as s.split(' '), (unless you redefine $;, but please don't do that).
We don't need self, so we omit it.

whats does .map(&:chomp) do, exactly? [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
What do you call the &: operator in Ruby?
I see '.map(&:chomp)' all the time
I know what chomp and map do, but I want to know what &: does and I'd like to know why I can't find it on the web after 30 minutes of googling.....
It's Symbol#to_proc, and it turns the symbol into a proc which attempts to invoke the given method on its argument, returning the result.
x = :reverse.to_proc
x.call("asdf") # "fdsa", like calling "asdf".reverse
In your case, .map(&:chomp) is equivalent to .map { |x| x.chomp }.
If you can't find it by Googling, it's because you're Googling the wrong thing. It's a well-known Ruby idiom.

Resources