From: Ryan Davis on

On Feb 18, 2010, at 17:48 , Farhad Farzaneh wrote:

> Ryan Davis wrote:
>> On Feb 18, 2010, at 16:04 , Farhad Farzaneh wrote:
>>
>>>> yet, and hasn't affected the lookup tables.
>>> value. As such, if we're ever going to use defined? as a conditional,
>>> it should precede any other mention of the token (foo).
>>
>> I should also point out: almost all of this is of no consequence. You
>> almost never use defined? on a local variable like this. You usually use
>> it on a const, ivar, cvar, or global, and all of those are unambiguous.
>
> Thanks. I sometimes use it in Rails partials rendering, where I may
> pass an optional local variable, but if it isn't passed, I want to set
> it to some default value. Perhaps there's a better way of doing this...

var ||= default


From: Ryan Davis on

On Feb 18, 2010, at 23:06 , Albert Schlef wrote:

> Farhad Farzaneh wrote:
>>> I should also point out: almost all of this is of no consequence. You
>>> almost never use defined? on a local variable like this. You usually use
>>> it on a const, ivar, cvar, or global, and all of those are unambiguous.
>>
>> Thanks. I sometimes use it in Rails partials rendering, where I may
>> pass an optional local variable, but if it isn't passed, I want to set
>> it to some default value.
>
> BTW, I wonder,
>
> In templates, local variables are created dynamically (e.g., the
> programmer passes a hash of "variables" to the template engine). So how
> can Ruby know, in the template code, that a "name" refers to a variable?
> By default Ruby thinks names are method invocations and since there's no
> assignment, Ruby has no way to know these are variables...

that's a rails question. Please take it to a rubyonrails forum (or dig up the code--but I really don't recommend that).


From: Brian Candler on
Maybe it's clearer like this:

if false
foo = 123
end
puts foo # nil

puts bar # undefined local variable or method 'bar'

That is, for a bare word expression like 'foo' ruby has to decide
whether to parse it as a method call - as foo() or self.foo - or as a
local variable reference.

It makes the decision based on whether there has been a previous
assignment of the form "foo = ..." parsed earlier in the code. This is
regardless of whether the code is actually executed, because we haven't
started executing any of it yet.

"earlier" in the code is strictly left-to-right.

foo = 123 if not defined?(foo)

At the point of defined?, "foo = ..." has already been seen, and so
bareword foo is known to be a local variable, and therefore the symbol
is 'defined' as a local variable at this point in the source code,
whether or not an assignment has actually been made.
--
Posted via http://www.ruby-forum.com/.

From: Eric Christopherson on
On Thu, Feb 18, 2010 at 5:18 PM, Ryan Davis <ryand-ruby(a)zenspider.com> wrote:
> Your latter code snippet treats "fooo" in defined? as a method call. This is because the assignment inside the conditional hasn't been parsed yet, and hasn't affected the lookup tables.
>
> The former doesn't have this problem because the body of the conditional is parsed first.

And:

On Sat, Feb 20, 2010 at 5:28 AM, Brian Candler <b.candler(a)pobox.com> wrote:
> Maybe it's clearer like this:
>
>  if false
>    foo = 123
>  end
>  puts foo      # nil
>
>  puts bar      # undefined local variable or method 'bar'
>
> That is, for a bare word expression like 'foo' ruby has to decide
> whether to parse it as a method call - as foo() or self.foo - or as a
> local variable reference.
>
> It makes the decision based on whether there has been a previous
> assignment of the form "foo = ..." parsed earlier in the code. This is
> regardless of whether the code is actually executed, because we haven't
> started executing any of it yet.

I think I understand the gist of this -- if the parser has seen foo
already, it is considered "defined" -- but how does the distinction of
method vs. local variable matter in this context? As far as I can
tell, defined? works the same on local variable names and method
names.

From: Brian Candler on
Eric Christopherson wrote:
> So:
>
> def foo; 456; end unless defined? foo
> puts foo
>
> will print 456, because at parse time foo is undefined, even though it
> gets made into a method name at runtime.

Almost - perhaps I muddied things a bit. At parse time, in the above
code, foo is not 'undefined'; it is known that it must be a method name,
because it's not a local variable. But it's not known whether there will
be a method called foo at the time this code is executed.

So, the result of defined?(foo) is decided at runtime. But if foo is a
local variable at that point in the source code (which is decided at
parse time), then you always know that the result of defined?(foo) will
be "local-variable", since the parse tree contains "NODE_LVAR foo"; the
parser had already chosen foo to be a local variable, and this is a fact
which cannot be altered subsequently.

I don't think the MRI interpreter actually optimises away defined?(LVAR)
to a constant at parse time as I might have implied, but in theory it
could.

For methods, the result is not known until runtime. Example:

>> 2.times { puts defined?(foo); def foo; end }
nil
method
=> 2
--
Posted via http://www.ruby-forum.com/.

First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4
Prev: DXF Writer?
Next: System handling of undef_method