in ruby, when is a block not a block? [duplicate] - ruby

This question already has an answer here:
Ruby block and unparenthesized arguments
(1 answer)
Closed 7 years ago.
Jokes aside, I have a strange situation, I have some code:
def remotes(form,remotes)
personalised_form = form.dup
remotes.each do |ident,remote|
object = yield(ident)
result = remote.call(object)
insert_into_(personalised_form,ident,result)
end
personalised_form
end
And I'm seeing if it works like so:
pp remotes(forms,remotes) do |ident|
case(ident)
when :get_assets
'#Userobject'
end
end
The problem is that ruby seems to think I'm not passing a block to the remotes function.
Why is ruby insisting that I'm not passing a block? (it gives a no block given (yield) (LocalJumpError) specifically).
Thought it's not relevant, remotes is a hash containing key's and Procs, and form is just a specificly structured hash that has the result of the proc inserted into it using the ident to locate the correct insertion point

Ruby thinks you are passing the block to pp method, which simply ignores it. Try:
res = remotes(forms,remotes) do |ident|
case(ident)
when :get_assets
'#Userobject'
end
end
pp res

Related

Why doesn't my ruby method call work? (yield) [duplicate]

This question already has answers here:
Passing block into a method - Ruby [duplicate]
(2 answers)
Closed 2 years ago.
I can't figure out why I get this error message when I run my file on the console: no block given (yield) (LocalJumpError)
Here my code:
def block_splitter(array)
array.partition { |item| yield(item) }
end
beatles = ["John", "Paul", "Ringo", "George"]
puts block_splitter(beatles) do |beatle|
beatle.start_with?("P")
end
Thanks for your help!
It's a whitespace issue. Your problem is in this line:
puts block_splitter(beatles) do |beatle|
# ...
end
The above code is being interpreted like this:
puts(block_splitter(beatles)) do |beatle|
# ...
end
I.e. the ruby interpreter thinks that the block is being passed to the puts method, not the block_splitter method.
By assigning a variable and printing the result, you'll see that this works as expected:
result = block_splitter(beatles) do |beatle|
beatle.start_with?("P")
end
puts result
Or, you can define this as a 1-liner, and the ruby interpreter handles it like you expected:
puts block_splitter(beatles) { |beatle| beatle.start_with?("P") }
Or, you could wrap it in extra brackets:
puts(block_splitter(beatles) do |beatle|
beatle.start_with?("P")
end)
So there is a problem with missing parentheses. Ruby interpreter allow not to use those, but when You use nested method calls It's better (and sometimes necessary) to use them. To fix it You can do something like this
puts(block_splitter(beatles) do |beatle|
beatle.start_with?("P")
end)
Or even better
puts(block_splitter(beatles) {|beatle| beatle.start_with?("P")})

Why can't I print the result of reduce/inject directly [duplicate]

This question already has answers here:
Code block passed to each works with brackets but not with 'do'-'end' (ruby)
(3 answers)
Closed 4 years ago.
Found an interesting quirk in the ruby interpreter - at least in MRI 2.4.2.
As far as I can tell, each of the below code snippets should print '123'. If I try to print the result of reduce directly, I get NoMethodError: undefined method '' for 1:Integer (or whatever type the array contains) But if I first save the result and then print it, it works fine..
So, this code is broken:
puts [1,2,3].reduce('') do |memo, num|
memo + num.to_s
end
And this code works:
temp = [1,2,3].reduce('') do |memo, num|
memo + num.to_s
end
puts temp
These should work exactly the same, right? Should this be filed as a bug? Am I just missing something fundamental here?
I'd think it should at least show which method is trying to be called. Can't find anything in google about an undefined method without a method name...
You need parenthesis on the puts call. This works:
puts([1,2,3].reduce('') do |memo, num|
memo + num.to_s
end)
Normally you can avoid parenthesis, but sometimes the parser will find ambiguities and will just raise an error, like in your first case.

what is the difference between .capitalize and .capitalize!(or .map & .map!...etc.) and in ruby [duplicate]

This question already has answers here:
What is the purpose of "!" and "?" at the end of method names?
(5 answers)
Closed 6 years ago.
learning how to code with Ruby and was trying learn from test first.
and I stumbled something funny.
I was trying to capitalize every word but
title = 'stuart little'
a = title.split
a.each do |x|
x.capitalize
end
a.join(' ')
This one's result is 'stuart little'
but if I add the ! in capitalize
title = 'stuart little'
a = title.split
a.each do |x|
x.capitalize!
end
a.join(' ')
it ends up with the result I want which is 'Stuart Little'
just .capitalize should work shouldn't it? since I'm just capitalizing the words. and what makes .capitalize! work in this scenario?
When a method has a ! at the end in Ruby, it is commonly referred to as a bang-method. The exclamation point indicates that the method is the dangerous version of another method.
In this case, capitalize! will modify your string, while capitalize will return a new string object. Since you are later calling on your original objects (the strings in a), your code will only work with capitalize!. To make the code work with capitalize, you would have to set that index of the array to the result of the method, e.g. a[index] = x.capitalize
if you really want to learn I like to go to the source
for map for map!. the source would tell you what the difference is
map- Invokes the given block once for each element of self.
and
map! - Invokes the given block once for each element of self,
replacing the element with the value returned by the block.

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.

Ruby " yield row if block_given?" [duplicate]

This question already has answers here:
Why does Ruby use yield?
(4 answers)
Closed 9 years ago.
# Get our data back
def queryNewsTable
#conn.exec( "SELECT * FROM newslib" ) do |result|
result.each do |row|
yield row if block_given?
end
end
end
For this piece of code. I don't quite understand yield row if block_given?
can anybody point to any good article teaching about this or you can briefly explain it to me a little bit
thanks so much
This yield row if block_given? means that block which could be passed into the #queryNewsTable method(!), is evaluated with yield operator, in other words, if you pass the block into function #queryNewsTable:
queryNewsTable do
#some code
end
You will get the call to the code, for each of rows in the result variable.
NOTE: That for your case it will be better to optimize the code (if not dbtrigger is used):
# Get our data back
def queryNewsTable
#conn.exec( "SELECT * FROM newslib" ) do |result|
result.each do |row|
yield row
end
end if block_given?
end
Ask yourself how Hash.new works:
http://www.ruby-doc.org/core-2.1.0/Hash.html#method-c-new
It can take no argument, a single argument, or a block. If there is no argument, fetching the value for a non-existent key gives nil. If there is a block, fetching the value for a non-existent key gives whatever the block says to give. Clearly its implementation needs a way to ask "was there a block?" so that it knows which behavior to use. That is what block_given? does.
http://www.ruby-doc.org/core-2.1.0/Kernel.html#method-i-block_given-3F
As for yield, it is simply the way a method that has taken a block calls the block, passing it parameters as needed.
When you use functions like Enumerable#each, you typically pass in a block using {|arg| ... } or do ... end. The line yield row if block_given? checks to see if a block was supplied to this function call, and if it was, calls that block with row as an argument.
One way you might use this function would be:
queryNewsTable {|row| puts row}
This example would print each row of the query to standard output, since the block that does the printing gets called for each row in the query result. If no block were given, then that line would be ignored.

Resources