3 ms·
The following is wrong. Only read the rest of this reply if you want to see how dumb I am. This is not a bug. "a = 5 unless defined? a" is not meant to be eq
by figgs 17y ago
The following is wrong. Only read the rest of this reply if you want to see how dumb I am.
This is not a bug.
"a = 5 unless defined? a" is not meant to be equivalent to this:
unless defined? a
a = 5
end
It is supposed to be (and is) equivalent to this:
a = unless defined? a
5
end*
- angilly 17y agoThat makes sense, but I've never seen statement modifiers defined that way. Every explanation I've ever seen, the pickaxe included, seems to outright state, or at least imply, the former.
- pvg 17y agoI think it's easy to get confused here because there's a natural tendency to read and interpret 'unless' as English and the fact that assignment in Ruby is also implicit declaration. Once this happens - a = a is defined. It doesn't matter at all what comes after (as long as it keeps the expression syntactically valid) - a is defined. The only question remains is what will end up getting assigned to it. Try a = asdfgasdfweradsf it will complain there is no asdf... but a is defined.
- deleted 17y ago[deleted]
- gaius 17y agoThat definitely sounds like a bug to me. Either a statement is fully valid and is executed, or it isn't and it isn't. In Python: >>> a=b Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'b' is not defined >>> a Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined >>> I think that follows the POLA...
- angilly 17y agointeresting. in ruby: ra:~$ irb irb(main):001:0> defined? a => nil irb(main):002:0> defined? b => nil irb(main):003:0> a = b NameError: undefined local variable or method `b' for main:Object from (irb):3 irb(main):004:0> a => nil irb(main):005:0> b NameError: undefined local variable or method `b' for main:Object from (irb):5 irb(main):006:0> defined? a => "local-variable" irb(main):007:0> 'a' gets defined.
- pvg 17y agoDepends what you are astonished by, I suppose. As far as I can tell the Ruby behaviour has to do with the fact that Ruby variable definition appears to take place sometime before evaluation, maybe during parsing. So as long as the statement parses and looks like a variable definition/assignment, you get your variable. On evaluation, undefined variables cause barfage but in the case above, the a got defined before the statement was actually executed.
- gaius 17y agoWell, I am astonished that entering invalid code can cause a persistent state change within my interpreter. I can't think of any other REPL language in which that happens. OCaml: # let a=b;; Error: Unbound value b # a;; Error: Unbound value a # Haskell: Prelude> let a=b <interactive>:1:6: Not in scope: `b' Prelude> a <interactive>:1:0: Not in scope: `a' Prelude> Scheme: guile> (define a b) Backtrace: In standard input: 1: 0* (define a b) standard input:1:1: In expression (define a b): standard input:1:1: Unbound variable: b ABORT: (unbound-variable) guile> a ERROR: Unbound variable: a ABORT: (unbound-variable) You can see where my astonishment comes from...
- pvg 17y agoYeah I was a little surprised too. It looks like the parser just defines foo for any parsable foo = .... before anything actually runs. Kind of a funky design choice, especially for such a dynamic language.
- aaronblohowiak 17y agothis is wrong! >> a = 1 => 1 >> b = 2 => 2 >> a = 3 unless b==2 => nil >> a => 1 >> a = unless b==2 >> 2 >> end => nil >> a => nil The difference is in the variable definition semantics, not in the assignment semantics. Please do not spread this misinformation.
- figgs 17y agoMy bad. Thanks for clarifying that.