Gsub does not work with do/end block, only brackets

puts “abcdefg”.gsub(/abc/) do |x|
x.upcase
end

^This does not work. ArgumentError, it’s expecting the second argument
that’s required when a block is not provided.

puts “abcdefg”.gsub(/abc/) { |x|
x.upcase
}

^This works.

Why??

On 10/21/07, Michael C. [email protected] wrote:

^This works.

Why??

Because {} binds tighter than do end

puts “abcdefg”.gsub(/abc/) do |x|
x.upcase
end

Is parsed as:

puts “abcdefg”.gsub(/abc/) { |x|
x.upcase
}

^This works.

Why??

Because {} binds tighter than do end

(puts (“abcdefg”.gsub(/abc/))) do |x|
x.upcase
end

Which means that the block is associated with the call to puts rather
than gsub.

While

puts “abcdefg”.gsub(/abc/) { |x|
x.upcase
\ }

Is parsed as

puts (“abcdefg”.gsub(/abc/) { |x|
x.upcase
\ })

Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Braces have high precedence, do end has low precedence so with

puts “abcdefg”.gsub(/abc/) do |x|
x.upcase
end

puts is being passed the block, whereas in

puts “abcdefg”.gsub(/abc/) { |x|
x.upcase
}

gsub is being passed the block. If you want to use do end, you can do
something like

puts(“abcdefg”.gsub(/abc/) do |x|
x.upcase
end)

or

s = “abcdefg”.gsub(/abc/) do |x|
x.upcase
end
puts s

Fascinating, thanks.

On 22 Oct 2007, at 09:45, Michael C. wrote:

^This works.

Why??

It interprets the block you are trying to give to ‘gsub’ as a block
argument to ‘puts’ instead. Brackets remove the ambiguity:

irb(main):008:0> “abc”.gsub(/a/){|x| x.upcase}
=> “Abc”
irb(main):009:0> “abc”.gsub(/a/) do |x| x.upcase end
=> “Abc”
irb(main):010:0> puts “abc”.gsub(/a/){|x| x.upcase}
Abc
=> nil
irb(main):011:0> puts “abc”.gsub(/a/) do |x| x.upcase end
ArgumentError: wrong number of arguments (1 for 2)
from (irb):11:in `gsub’
from (irb):11
irb(main):012:0> puts(“abc”.gsub(/a/) do |x| x.upcase end)
Abc
=> nil

Alex G.

Bioinformatics Center
Kyoto University