2

I am trying to use a named group in a regex but it doesn't work:

module Parser
  def fill(line, pattern)
    if /\s#{pattern}\:\s*(\w+)\s*\;/ =~ line
      puts Regexp.last_match[1]
      #self.send("#{pattern}=", value)
    end
    if /\s#{pattern}\:\s*(?<value>\w+)\s*\;/ =~ line
      puts value
      #self.send("#{pattern}=", value)
    end
  end
end

As you can see I first test my regex then I try to use the same regex with a named group.

class Test
  attr_accessor :name, :type, :visible
  include Parser #add instance method (use extend if we need class method)
  def initialize(name)
    @name = name
    @type = "image"
    @visible = true
  end
end

t = Test.new("toto")
s='desciption{ name: "toto.test"; type: RECT; mouse_events: 0;'
puts t.type
t.fill(s, "type")
puts t.type

When I execute this, the first regex work but not the second with the named group. Here is the output:

./ruby_mixin_test.rb
image
RECT
./ruby_mixin_test.rb:11:in `fill': undefined local variable or method `value' for 
#<Test:0x00000001a572c8> (NameError)
from ./ruby_mixin_test.rb:34:in `<main>'

2 Answers 2

7

If =~ is used with a regexp literal with named captures, captured strings (or nil) is assigned to local variables named by the capture names.

/(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/ =~ "  x = y  "
p lhs    #=> "x"
p rhs    #=> "y"

But - A regexp interpolation, #{}, also disables the assignment.

rhs_pat = /(?<rhs>\w+)/
/(?<lhs>\w+)\s*=\s*#{rhs_pat}/ =~ "x = y"
lhs    # undefined local variable

In your case from the below code :

if /\s#{pattern}\:\s*(?<value>\w+)\s*\;/ =~ line
   puts value
   #self.send("#{pattern}=", value)
end

Look at the line below, you use interpolation

/\s#{pattern}\:\s*(?<value>\w+)\s*\;/ =~ line
 ~~^

Thus local variable assignment didn't happen and you got the error as you reported undefined local variable or method 'value'.

Sign up to request clarification or add additional context in comments.

2 Comments

your answer is very ineresting. Have you some sources please?
If you are looking for a solution, then it seems from tinkering that although lhs is not set, $~[:lhs] is, so perhaps that is the best workaround?
1

You have not defined value in the module

if /\s#{pattern}\:\s*(?<value>\w+)\s*\;/ =~ line
  puts value  # This is not defined anywhere
  [..]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.