1

Consider this block of code:

f = File.new('test')
f.each_line { |line|
  if line =~ /@b/ then
    x = line
  end
}
y = x[/<(.*)>/,1]

This is f:

@a <1,2,3>
@b <'whatever'>
@c <['x','y','z']
@d <1.1>

and Originally, this block of code was working, returning y as 'whatever', but is now throwing this error:

Traceback (most recent call last):
        4: from C:/Ruby26-x64/bin/irb.cmd:31:in `<main>'
        3: from C:/Ruby26-x64/bin/irb.cmd:31:in `load'
        2: from C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        1: from (irb):10
NameError (undefined local variable or method `x' for main:Object)

Any suggestions?

P.S.

This is being run directly through irb

3
  • What statement is on line 10 ('10' being from your error message)? You need to pay careful attention to error messages; often the pinpoint the problem. Commented Dec 19, 2019 at 7:25
  • 3
    You are aware that if multiple lines match @b then x will only represent the last one correct? Commented Dec 19, 2019 at 14:02
  • If you want all matches you could do something like: lines = File.foreach('test').grep(/@b/) Commented Dec 19, 2019 at 17:05

2 Answers 2

4

x is being defined in the local context of the block, and once the context of the block is left it is no longer defined. So variable x needs to be defined outside the context of the block:

x = nil
f = File.new('test')
f.each_line { |line|
  if line =~ /@b/ then
    x = line
  end
}
y = x[/<(.*)>/,1]
Sign up to request clarification or add additional context in comments.

1 Comment

You might show how you are using the initial value of x in the event that no line matches /@b/: y = x.nil? ? nil : x[/<(.*)>/,1].
2

Scope. Define x, then run in irb, and note that it works…

x = 'not in scope'
f = File.new('test')
f.each_line { |line|
  if line =~ /@b/ then
    x = line
  end
}
y = x[/<(.*)>/,1]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.