map = { “arup” => “1989”}
puts “arup rakshit”.gsub(/(arup)rakshit/, map[\1] ) # !> possibly
useless use of a literal in void context
\1 isn’t a variable name, it’s a string escape sequence. It will only
work
inside a string. Try either map[’\1’] or map[$1]
(I just woke up so my head may still be cloudy.)
Oh, and you may need the block mode of #gsub
Final thing: your regex won’t match your string, because the /rakshit/
part
is non-optional.
Matthew K. wrote in post #1139645:
\1 isn’t a variable name, it’s a string escape sequence. It will only
work
inside a string. Try either map[’\1’]
map = { “arup” => “1989”}
puts “arup rakshit”.gsub(/(arup)\s+rakshit/, map[’\1’] )
~> -:2:in `gsub’: no implicit conversion of nil into String
(TypeError)
~> from -:2:in `’
or map[$1]
map = { “arup” => “1989”}
puts “arup rakshit”.gsub(/(arup)\s+rakshit/, map[$1] )
~> -:2:in `gsub’: no implicit conversion of nil into String
(TypeError)
~> from -:2:in `’
$1,$2 etc work with blocks.
(I just woke up so my head may still be cloudy.)
My question is when the below is working :
map = { “arup” => “1989”} # !> assigned but unused variable - map
puts “arup rakshit”.gsub(/(arup)\s+rakshit/, ‘<\1>’ )
>>
Why not below ?
map = { “arup” => “1989”}
puts “arup rakshit”.gsub(/(arup)\s+rakshit/, map[’\1’] )
~> -:2:in `gsub’: no implicit conversion of nil into String
(TypeError)
~> from -:2:in `’
Arup R. wrote in post #1139651:
My question is when the below is working :
map = { “arup” => “1989”} # !> assigned but unused variable - map
puts “arup rakshit”.gsub(/(arup)\s+rakshit/, ‘<\1>’ )>>
Why not below ?
map = { “arup” => “1989”}
puts “arup rakshit”.gsub(/(arup)\s+rakshit/, map[’\1’] )~> -:2:in `gsub’: no implicit conversion of nil into String
(TypeError)
~> from -:2:in `’
Ah, this is a timing issue. You have to consider the point (in time) at
which each expression is evaluated.
For example:
‘abc’.gsub(/b/, ‘<\1>’)
- ‘abc’ is evaluated, to give the String object
- .gsub is looked up in the method table
- /b/ is evaluated, to give a Regexp object
- ‘<\1>’ is evaluated, to give a String object
- String#gsub is invoked, with ‘abc’, /b/, ‘<\1>’ as
receivers/parameters, resulting in your output
versus:
‘abc’.gsub(/b/, map[’\1’])
- ‘abc’ is evaluated, to give the String object
- .gsub is looked up in the String’s method table
- /b/ is evaluated, to give a Regexp object
- map is looked up in the lvar table, giving a Hash object
- [] is looked up in the Hash’s method table
- ‘\1’ is evaluated, giving a String object
- Hash#[] is invoked, with map, ‘\1’ as receivers/parameters,
resulting innil
- String#gsub is invoked, with ‘abc’, /b/, nil as
receivers/parameters, resulting in failure
Also note that the “\1” backref only works when it’s present in the
string given as the second parameter to #gsub
Matthew K. wrote in post #1139656:
Arup R. wrote in post #1139651:
Also note that the “\1” backref only works when it’s present in the
string given as the second parameter to #gsub
Nice explanation. Yes, that specific stuffs very hard to recognize in
Ruby. When I am sending '<\1>'
, all is ok. But when trying to do it
map['\1']
or "#{map[\\1]}"
objections.
so back-reference is not a global operation with gsub
, it has a
limitations.