Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
391 views
in Technique[技术] by (71.8m points)

ruby - Variable scope and order of parsing vs. operations: Assignment in an "if"

My understanding is that the if statements at the end of the line are evaluated before the code at the front of the line:

'never shown' if (false)

And assignment is possible in an if statement.

'shown' if (value = 'dave is king')
value #=> "dave is king"

And, when a variable that doesn't exist is assigned to, it is created. There is no need for it to exist beforehand. Is this true?

If all these assumptions are true, why does this fail?

error_array << error if (error = import_value(value))
#=> undefined local variable or method `error' for

It assigned to error before the array push right? I want to understand when things are evaluated.

This one does work:

if (error = import_value(value))
  error_array << error
end

Now I'm really confused.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It only happens when you try to assign a literal value, if you call a function it works.

def foo(a)
  a
end

p 'not shown' if(value = foo(false))
p 'shown' if(value = foo(true))

# This outputs a Warning in IRB
p 'shown' if(value = false)
(irb):2: warning: found = in conditional, should be ==

If you turn on debugging (-d) you will see a warning about an used variable value

warning: assigned but unused variable - value

This "works" because the statement does evaluate to true as far as if is concerned, allowing the code preceeding it to run.

What is happening here is that if() when used as a modifier has it's own binding scope, or context. So the assignment is never seen outside of the if, and therefore makes no sense to perform. This is different than if the control structure because the block that the if statement takes is also within the same scope as the assignment, whereas the line that preceeded the if modifier is not within the scope of the if.

In other words, these are not equivelant.

if a = some(value)
  puts a
end

puts a if(a = some(value))

The former having puts a within the scope of the if, the latter having puts a outside the scope, and therefore having different bindings(what ruby calls context).

Ruby Order of Operations


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...