Strings combine

I think this is really the key here. With this code, we have two literal
objects:

    'foo' 'bar'

With this code, however, we have references to objects:

    a = 'foo'
    b = 'bar'
    a b

. . . which would be why they behave differently in terms of the
principles of the Ruby language's design.

That . . . or it's an accident of implementation. I guess the question
then is whether the fact that references to string objects behave
differently from literal string objects in this case is the result of a
conscious decision or just an emergent property of the implementation.

···

On Sat, Feb 20, 2010 at 09:59:54AM +0900, Rick DeNatale wrote:

Second, variables in Ruby are untyped references to objects, and not
objects themselves.

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

Rick Denatale wrote:

In the expression

   x y

It sees x as a method because of the form of the expression.

And to prove this:

irb(main):001:0> x y
NameError: undefined local variable or method `y' for main:Object
  from (irb):1

That is: ruby has already decided from *parsing* that x could only be a
method name. Actually x is neither a method nor a local variable right
now, but when parsing it doesn't know this. So it's parsed as x(y), and
the first thing it errors on when trying to execute that expression is
that y is undefined, as you evaluate all the args before performing the
method call.

irb(main):002:0> y = nil
=> nil
irb(main):003:0> x y
NoMethodError: undefined method `x' for main:Object
  from (irb):3

So:

  x y is unambiguously saying x is a method, y is arg
  self.x is unambiguously saying that x is a method
  x() is unambiguously saying that x is a method

The only time where ruby has to probe further is an expression like
this:

  x

Then it looks to see if there has been a previous expression of the form
x = ... in the current scope. If so, x is a local variable. If not, x is
a method.

So the current rules let us know unambigously that

  puts "hello"

is always a method call, without having to think any further. Even the
following oddball example works in a fairly understandable way:

  puts = "abc"
  puts "hello"
  puts puts

If you decided to change the parsing just to allow concatenation of
adjacent items it would become horrendously complicated to read ruby
source. For example, the line

  puts "hello"

*might* be a method call, or it *might* be concatenation, depending on
whether puts was a local variable or not. That means you couldn't
understand any source without continually looking back at the previous
lines in the method.

In any case, just look at the C language for an example where
concatenating adjacent string *literals* is implemented, but it would
make no sense at all to concatenate two adjacent expressions, because
the language doesn't even have a string concatentation operator.

  char *c0 = "abc" "def"; // 7 bytes, abcdef\0

I suspect this is where Ruby inherited this feature from.

···

--
Posted via http://www.ruby-forum.com/\.

Ahhh. I had assumed that the ruby parser kept a running list of defined
methods/defined variables. Thanks for clearing that up.

···

--
Posted via http://www.ruby-forum.com/.