Evaluation order

One interesting thing is when running the following codes

File.open("testfile") |aFile| do
   print a while a=aFile.gets
end

one will get an error indicating a doesn't exist. This error can be
fixed by adding a line a="" before the print command.

But logically speaking, "print a" should be interpreted after
"a=File.gets". Is this because the interpreter couldn't find the object
"a" when first scanning the second line?

(In response to news:1108274165.071278.164610@z14g2000cwz.googlegroups.com
by Zehao)

File.open("testfile") |aFile| do
   print a while a=aFile.gets
end

Isn't that File.open('testfile') do |aFile| ?

k

"Zehao" <zehao.chen@gmail.com> schrieb im Newsbeitrag news:1108274165.071278.164610@z14g2000cwz.googlegroups.com...

One interesting thing is when running the following codes

File.open("testfile") |aFile| do
  print a while a=aFile.gets
end

one will get an error indicating a doesn't exist. This error can be
fixed by adding a line a="" before the print command.

But logically speaking, "print a" should be interpreted after
"a=File.gets". Is this because the interpreter couldn't find the object
"a" when first scanning the second line?

I suspect it's the same issue as with local variables: Ruby applies a certain heuristic to determine whether something is a local var or not. This heuristic is based on *syntactical* order of occurrence

def foo
print a
a = 10
end

=> nil

foo

NameError: undefined local variable or method `a' for main:Object
        from (irb):2:in `foo'
        from (irb):5

See also
http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html#UO
http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html#S3

Kind regards

    robert

Hi --

"Zehao" <zehao.chen@gmail.com> schrieb im Newsbeitrag news:1108274165.071278.164610@z14g2000cwz.googlegroups.com...

One interesting thing is when running the following codes

File.open("testfile") |aFile| do
  print a while a=aFile.gets
end

one will get an error indicating a doesn't exist. This error can be
fixed by adding a line a="" before the print command.

But logically speaking, "print a" should be interpreted after
"a=File.gets". Is this because the interpreter couldn't find the object
"a" when first scanning the second line?

I suspect it's the same issue as with local variables: Ruby applies a certain heuristic to determine whether something is a local var or not. This heuristic is based on *syntactical* order of occurrence

def foo
print a
a = 10
end

=> nil

foo

NameError: undefined local variable or method `a' for main:Object
      from (irb):2:in `foo'
      from (irb):5

It's also fun to see what happens if you run this kind of thing twice:

irb(main):005:0> puts x if x = 1
NameError: undefined local variable or method `x' for main:Object
         from (irb):5
irb(main):006:0> puts x if x = 1
1

(For clarity I've deleted the warning about using '=' in conditional.
[Matz, can't we get rid of that warning?])

David

···

On Sun, 13 Feb 2005, Robert Klemme wrote:

--
David A. Black
dblack@wobblini.net

I'd love per-warning suppressibility, but if not, I think this particular
one does more good than harm. (But then, I find the if (a = f(x)) idiom
rather ugly to begin with).

martin

···

David A. Black <dblack@wobblini.net> wrote:

(For clarity I've deleted the warning about using '=' in conditional.
[Matz, can't we get rid of that warning?])

Hi --

(For clarity I've deleted the warning about using '=' in conditional.
[Matz, can't we get rid of that warning?])

I'd love per-warning suppressibility, but if not, I think this particular
one does more good than harm. (But then, I find the if (a = f(x)) idiom
rather ugly to begin with).

I'm trying to figure out the pattern behind when it gets triggered or
not:

   irb(main):002:0> while (x = 1); end
   (irb):2: warning: found = in conditional, should be ==
   irb(main):003:0> while (line = gets); end
   abc
   ^D
   => nil
   irb(main):004:0> if (m = /a/.match("b")); end
   => nil
   irb(main):005:0> if (m = /a/); end
   (irb):5: warning: found = in conditional, should be ==
   irb(main):006:0> if (m = "abc".replace("abc")); end
   => nil
   irb(main):007:0> if (m = "abc"); end
   (irb):7: warning: found = in conditional, should be ==
   => nil

When the rhs is a literal, I guess? That at least vastly increases
the chances of its being a case of a typo. Could it be that Matz is
several steps ahead of me? :slight_smile:

David

···

On Sun, 13 Feb 2005, Martin DeMello wrote:

David A. Black <dblack@wobblini.net> wrote:

--
David A. Black
dblack@wobblini.net

"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag news:Pine.LNX.4.61.0502130707250.22113@wobblini...

Hi --

(For clarity I've deleted the warning about using '=' in conditional.
[Matz, can't we get rid of that warning?])

I'd love per-warning suppressibility, but if not, I think this particular
one does more good than harm. (But then, I find the if (a = f(x)) idiom
rather ugly to begin with).

I'm trying to figure out the pattern behind when it gets triggered or
not:

  irb(main):002:0> while (x = 1); end
  (irb):2: warning: found = in conditional, should be ==
  irb(main):003:0> while (line = gets); end
  abc
  ^D
  => nil
  irb(main):004:0> if (m = /a/.match("b")); end
  => nil
  irb(main):005:0> if (m = /a/); end
  (irb):5: warning: found = in conditional, should be ==
  irb(main):006:0> if (m = "abc".replace("abc")); end
  => nil
  irb(main):007:0> if (m = "abc"); end
  (irb):7: warning: found = in conditional, should be ==
  => nil

When the rhs is a literal, I guess? That at least vastly increases
the chances of its being a case of a typo. Could it be that Matz is
several steps ahead of me? :slight_smile:

:-))

Note also, that assignment in a conditional really only makes sense for loops. With "if" and "unless" it's totally superfluous since you can always do

a=x
if a then...

instead of

if a=x then...

And it's also more readable. So I would not mind if there was *always* a warning for assignment if it's "if" or "unless". Just my 0.02 EUR though...

Whereas there is no easy equivalent replacement for

while ( line = gets ) ...

Typically, you would need two assignments which is somewhat ugly:

line = gets
while line
....
  line = gets
end

Kind regards

    robert

···

On Sun, 13 Feb 2005, Martin DeMello wrote:

David A. Black <dblack@wobblini.net> wrote:

Hi,

···

Am Montag, 14. Feb 2005, 01:39:57 +0900 schrieb Robert Klemme:

while ( line = gets ) ...

Typically, you would need two assignments which is somewhat ugly:

line = gets
while line
....
line = gets
end

There is

  while gets
    line = $_.chomp
    ...
  end

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

I will occasionally use the a=x in an elsif statement. Generally when the 'x'
part looks up something that I want to process in the elsif part. E.g.

  if parent.nil?
    handle_no_parent
  elsif children = parent.get_children
    do_somthing_with(children)
  else
    do_something_else
  end

Probably a bad example, but you get my drift.

···

On Sunday 13 February 2005 11:39 am, Robert Klemme wrote:

Note also, that assignment in a conditional really only makes sense for
loops. With "if" and "unless" it's totally superfluous since you can
always do

a=x
if a then...

--
-- Jim Weirich jim@weirichhouse.org http://onestepback.org
-----------------------------------------------------------------
"Beware of bugs in the above code; I have only proved it correct,
not tried it." -- Donald Knuth (in a memo to Peter van Emde Boas)

"Bertram Scharpf" <lists@bertram-scharpf.de> schrieb im Newsbeitrag news:20050213171916.GA31424@homer.bertram-scharpf...

Hi,

while ( line = gets ) ...

Typically, you would need two assignments which is somewhat ugly:

line = gets
while line
....
line = gets
end

There is

while gets
   line = $_.chomp
   ...
end

Bertram

That's a special case that works only because gets() does not only return the value but assigns it to $_ as a side effect. In the general case you need two assignments unless you put it into the while condition.

Kind regards

    robert

···

Am Montag, 14. Feb 2005, 01:39:57 +0900 schrieb Robert Klemme: