|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
7stud -- wrote:
>David Black wrote: >The second time through >the loop, there's no assignment to a, and the first variable a has >gone out of scope. > Wait a minute. 'a' has gone out of scope? for i in 1..2 if i == 1 a = 10 print "a=", a, "\n" else puts a end end puts "*#{a}" puts a --output:-- a=10 10 *10 In ruby, for loops and if clauses don't create a scope. -- Posted via http://www.ruby-forum.com/. |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
7stud -- wrote:
> That doesn't seem to bear out. If you switch the if statement around so > that the assignment happens first: > > def x > print "Function 'x' called\n" > 99 > end > > The difference between the both examples is the following: Ruby parses this: for i in 1..2 if i == 2 print "a=", a, "\n" >> Here Ruby decides, that "a" must mean the a method and creates the call-method node in its tree. else a = 1 >> Here Ruby decides, a is a local variable. print "a=", a, "\n" >> Here Ruby creates a evaluate-local-variable node in its tree. end end In your example: > for i in 1..2 > if i == 1 > x = 1 > >> Here Ruby decides, "x" is a local variable. > print "x=", x, "\n" > >> Here Ruby creates a evaluate-local-variable node in its tree. > else > print "x=", x, "\n" > >> Sticks to its former decision, that "x" is local variable, and creates a evaluate-local-variable node in its tree. > end > end > This is an interaction between parsing and execution or ruby code, and it can be a bit surprising. The later execution (== comparisons, etc.) doesn't alter the behavior of the parser, which does its jobs earlier. -- Florian Frank |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
RnJvbTogN3N0dWQgLS0gW21haWx0bzpkb2xndW5AZXhjaXRlLm NvbV0gDQojIEluIHJ1YnksIGZv
ciBsb29wcyBhbmQgaWYgY2xhdXNlcyBkb24ndCBjcmVhdGUgYS BzY29wZS4NCg0KaXJiKG1haW4p OjAwMTowPiBpZiBmYWxzZQ0KaXJiKG1haW4pOjAwMjoxPiAgIC B4DQppcmIobWFpbik6MDAzOjE+ IGVuZA0KPT4gbmlsDQppcmIobWFpbik6MDA0OjA+IHgNCk5hbW VFcnJvcjogdW5kZWZpbmVkIGxv Y2FsIHZhcmlhYmxlIG9yIG1ldGhvZCBgeCcgZm9yIG1haW46T2 JqZWN0DQogICAgICAgIGZyb20g KGlyYik6NA0KaXJiKG1haW4pOjAwNTowPiBpZiBmYWxzZQ0KaX JiKG1haW4pOjAwNjoxPiAgICB4 ID0gNQ0KaXJiKG1haW4pOjAwNzoxPiBlbmQNCj0+IG5pbA0KaX JiKG1haW4pOjAwODowPiB4DQo9 PiBuaWwNCg0KdGhleSBjYW4gaW50cm9kdWNlIGEgdmFyICh1bm RlciB0aGUgZXhpc3RpbmcgbG9j YWwgc2NvcGUgb2YgY291cnNlKS4NCmkgdGhpbmsgaXRzIGluIH RoZSBhc3NpZ25tZW50IGJlaGF2 aW91ciBpZiB5b3UgbG9vayBhdCBpdC4gIHBhcnNlciBzZWVzIG Fzc2lnbm1lbnQgZXZlbiBpZiBj b2RlIGlzIG5vdCBleGVjdXRlZC4NCnJ1YnkganVzdCB0cnkgdG 8gYmUgZnJpZW5kbHksIGJ1dCB5 b3UgY2FuIGJlIHNsb3BweSBpZiB5b3Ugd2FudCB0byBhbmQgcn VieSB3aWxsIG5vdCBnaXZlIHlv dSBhbiBlcnJvciA6KQ0KYWdhaW4sIGkgdGhpbmsgdGhpcyBpcy BhIGZhcS4NCg0Ka2luZCByZWdh cmRzIC1ib3RwDQo= |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Hi,
7stud -- wrote: > David A. Black wrote: > As p. 329 in pickaxe2 carefully explains, it is a ruby parsing rule that > determines what x means. As I read the rule, and as Daniel explains, > and as the two examples show(the 'a' example and the 'x' example), the > rule is: if there is any code that has x=val on a line before the use of > x, then x will be interpreted as a variable. If there is no assignment > to x on a line higher in the code, then x will be interpreted as a > method call. Please, look at this 2 examples of "parse-time": 1) > pp ParseTree.translate('bar = 3 define_method(:foo) do bar end') [:block, [:lasgn, :bar, [:lit, 3]], [:iter, [:fcall, :define_method, [:array, [:lit, :foo]]], nil, [:lvar, :bar]]] 2) > pp ParseTree.translate('bar = 3 def foo bar end') [:block, [:lasgn, :bar, [:lit, 3]], [:defn, :foo, [:scope, [:block, [:args], [:vcall, :bar]]]]] *** In 1) we see a :lvar node, whereas in 2) we see a :vcall. From my interpretation of p.329 of pickaxe2 i do not agree with the 2nd case (but probably it's my problem - comment please). In the 2nd case, IMHO, we should see a lvar node. This may seem a detail, but i was bitten by that a few minutes ago. Let me show a simplified example: bar = "test" c = Class.new c.class_eval do def foo bar end end > c.new.foo NameError: undefined local variable or method `bar' # i was expecting to get "test" The (hack) "solution" (it's a hack because IMHO i shouldn't have to do that): bar = "test" c = Class.new c.class_eval do define_method(:foo) do bar end end > c.new.foo "test" Note: only one more thing, since ruby 1.8 have a "problem" with block (it can't get other blocks - &block in argument) this could be a problem. I know you can hack these thing through a method - but that's another hack :P... too much hacks for me :-) I would appreciate very much all your comments about the current behavior of ruby (1.8). Regards, Vasco Andrade e Silva -- Posted via http://www.ruby-forum.com/. |
|
![]() |
| Outils de la discussion | |
|
|