My first feeling of Ruby

Hi all,

Today I'm learning Ruby. Globally It's a great programming langage but I've noticed some irrationnal things:

First thing:

···

============
irb(main):138:0* class Toto
irb(main):139:1> @@test="a"
irb(main):140:1>
irb(main):141:1* def test
irb(main):142:2> @test="b"
irb(main):143:2> test="c"
irb(main):144:2> puts "test #@@test"
irb(main):145:2> puts "test #@test"
irb(main):146:2> puts "test #test" # #{test} instead #test why?
irb(main):147:2> end
irb(main):148:1> end
=> nil
irb(main):149:0> Toto.new.test
test a
test b
test #test
=> nil

Why #test doesn't work for local variables? It would be more logic. It's my point of view. We can have both #test and #{test} working.

Second thing:

hastables is using a mix of {} and []. Always using {} or [] (but not both) for hastable would be "errorless".

Actually {} for initialisation:
irb(main):150:0> hash = { "A"=>1 , "B"=>2 }
=> {"A"=>1, "B"=>2}

[] for reading:
irb(main):152:0> hash["A"]
=> 1

If you go wrong:
irb(main):156:0> hash{"A"}
=> 537984250
irb(main):154:0> hash = [ "A"=>1 , "B"=>2 ]
=> [{"A"=>1, "B"=>2}]

I would prefer an error or warning. The last line means I can omit {}? so let's go on:

irb(main):155:0> hash = "A"=>1 , "B"=>2
SyntaxError: compile error
(irb):155: parse error, unexpected tASSOC, expecting $
hash = "A"=>1 , "B"=>2
             ^
         from (irb):155
         from :0
irb(main):156:0>

Hmm why [ "A"=>1 , "B"=>2 ] silently produce [{"A"=>1, "B"=>2}] ?

my 2c,
Florent,

I'm sure someone who's knows way more than me about Ruby's internals
will supply a technical reason for it, but, personally, I prefer #{the
current syntax}, because, to me, it's less ambiguous and allows for
complex expressions inside the curly brackets.

As for the hashes, it just happens that is the name of the method
that retrieves a certain element from a collection. If you look at it
this way, it becomes quite logical for both collections to have the
same syntax.

···

On 10/18/06, Florent Guiliani <fguiliani@perinfo.com> wrote:

Why #test doesn't work for local variables? It would be more logic. It's
my point of view. We can have both #test and #{test} working.

--
Bira

http://sinfoniaferida.blogspot.com

Frankly I never knew you could do "test #@@varname". I've always used the
#{} syntax.

As for part 2, that is purely an issue with the parser.

hash = "A" => 1, "B" => 2

- Where would the parser end? Ruby allows this:

a, b = 1, 2

so your attempt at assigning a hash as such is a syntax error, as you found
out. As function calls however:

def func1(options = {}); ... ; end

you're allowed to do what seems to be the same thing because the parser is
now grabbing parameters until the end of the line:

func1 :key => '1', :key2 => '2'

is the same as

func1(:key => '1', :key2 => '2')

is the same as

func1( {:key => '1', :key2 => '2'} )

As for "Hmm why [ "A"=>1 , "B"=>2 ] silently produce [{"A"=>1, "B"=>2}] ?",
the parser sees that you want an array. Arrays don't have keys and so for
the same reason as the function parameter syntax, it sees key/value pairs
and creates a hash.

Jason

···

On 10/18/06, Florent Guiliani <fguiliani@perinfo.com> wrote:

Hi all,

Today I'm learning Ruby. Globally It's a great programming langage but
I've noticed some irrationnal things:

First thing:

irb(main):138:0* class Toto
irb(main):139:1> @@test="a"
irb(main):140:1>
irb(main):141:1* def test
irb(main):142:2> @test="b"
irb(main):143:2> test="c"
irb(main):144:2> puts "test #@@test"
irb(main):145:2> puts "test #@test"
irb(main):146:2> puts "test #test" # #{test} instead #test why?
irb(main):147:2> end
irb(main):148:1> end
=> nil
irb(main):149:0> Toto.new.test
test a
test b
test #test
=> nil

Why #test doesn't work for local variables? It would be more logic. It's
my point of view. We can have both #test and #{test} working.

Second thing:

hastables is using a mix of {} and . Always using {} or (but not
both) for hastable would be "errorless".

Actually {} for initialisation:
irb(main):150:0> hash = { "A"=>1 , "B"=>2 }
=> {"A"=>1, "B"=>2}

for reading:
irb(main):152:0> hash["A"]
=> 1

If you go wrong:
irb(main):156:0> hash{"A"}
=> 537984250
irb(main):154:0> hash = [ "A"=>1 , "B"=>2 ]
=> [{"A"=>1, "B"=>2}]

I would prefer an error or warning. The last line means I can omit {}?
so let's go on:

irb(main):155:0> hash = "A"=>1 , "B"=>2
SyntaxError: compile error
(irb):155: parse error, unexpected tASSOC, expecting $
hash = "A"=>1 , "B"=>2
             ^
         from (irb):155
         from :0
irb(main):156:0>

Hmm why [ "A"=>1 , "B"=>2 ] silently produce [{"A"=>1, "B"=>2}] ?

my 2c,
Florent,

Florent Guiliani wrote:

Hi all,

Today I'm learning Ruby. Globally It's a great programming langage but
I've noticed some irrationnal things:

First thing:

irb(main):138:0* class Toto
irb(main):139:1> @@test="a"
irb(main):140:1>
irb(main):141:1* def test
irb(main):142:2> @test="b"
irb(main):143:2> test="c"
irb(main):144:2> puts "test #@@test"
irb(main):145:2> puts "test #@test"
irb(main):146:2> puts "test #test" # #{test} instead #test why?
irb(main):147:2> end
irb(main):148:1> end
=> nil
irb(main):149:0> Toto.new.test
test a
test b
test #test
=> nil

Why #test doesn't work for local variables? It would be more logic. It's
my point of view. We can have both #test and #{test} working.

I don't most of us use those shorcuts, prefering to alwasy use #{...}
notation:

  puts "test #{@@test}"
  puts "test #{@test}"
  puts "test #{test}"

Second thing:

hastables is using a mix of {} and . Always using {} or (but not
both) for hastable would be "errorless".

Actually {} for initialisation:
irb(main):150:0> hash = { "A"=>1 , "B"=>2 }
=> {"A"=>1, "B"=>2}

for reading:
irb(main):152:0> hash["A"]
=> 1

If you go wrong:
irb(main):156:0> hash{"A"}
=> 537984250
irb(main):154:0> hash = [ "A"=>1 , "B"=>2 ]
=> [{"A"=>1, "B"=>2}]

I would prefer an error or warning. The last line means I can omit {}?
so let's go on:

I have to agree with you here. But the issue is a much larger one.
Because Ruby handles the trailing block argument as a special case it
is always an optional argument. So any method can take a block and not
raise an error:

  puts { blah!.nothing.matters } => "\n"

So in your case you are actually calling the #hash method which
actually has nothing to do with a Hash class, and your throwing in a
meaningless block to go with it.

I'd rather have blocks be passed in as the trailing argument
regardless, such that the special '&argument' were not needed at all.
This would improve method interfaces.

On another note, I always thought it would be nice to have a merged
Hash/Array, call it "Collection" if you will, such that

  c = Collection.new
  c[index] # lookup by index
  c{key} # lookup by key

But that notation might cause other conflicts.

irb(main):155:0> hash = "A"=>1 , "B"=>2
SyntaxError: compile error
(irb):155: parse error, unexpected tASSOC, expecting $
hash = "A"=>1 , "B"=>2
             ^
         from (irb):155
         from :0
irb(main):156:0>

Hmm why [ "A"=>1 , "B"=>2 ] silently produce [{"A"=>1, "B"=>2}] ?

Any method can take hash elements which are "silently" converted to a
hash. So:

  def foo(arg)
    p arg
  end

  foo( "A"=>1 , "B"=>2 ) #=> {"A"=>1 , "B"=>2}

The same is true for # which is also a method!

Some of us howerver would like to see [ "A"=>1 , "B"=>2 ] be
interpreted as an ordered hash instead if reasonably possible.

HTH,
T.

Florent Guiliani wrote:

Hi all,

Today I'm learning Ruby. Globally It's a great programming langage but I've noticed some irrationnal things:

Welcome to Ruby!

I recommend that you use Ruby with an open mind for 4-6 weeks before making any judgments about it. That gives you time to learn how things in Ruby fit together. At first some things may seem arbitrary but after a while you see that there are good reasons for Ruby to be the way it is.

After you've finished a medium-sized project come back and let us know what you think.

Florent Guiliani wrote:

Why #test doesn't work for local variables? It would be more logic. It's my point of view. We can have both #test and #{test} working.

For one thing, test could just as easily be a method name. This
might lead people to think that the parameters followed it in
the string.

Things such as #$foo and #@foo are special cases. A single char
tells us that it's a simple variable.

The general case is #{...} and can be any arbitrary expression.

Second thing:

hastables is using a mix of {} and . Always using {} or (but not both) for hastable would be "errorless".

Conflict with block syntax. You can't say hash {"A"} meaningfully.
In fact, I'm not certain why that returns an integer.

Hal

···

Actually {} for initialisation:
irb(main):150:0> hash = { "A"=>1 , "B"=>2 }
=> {"A"=>1, "B"=>2}

for reading:
irb(main):152:0> hash["A"]
=> 1

If you go wrong:
irb(main):156:0> hash{"A"}
=> 537984250
irb(main):154:0> hash = [ "A"=>1 , "B"=>2 ]
=> [{"A"=>1, "B"=>2}]

I would prefer an error or warning. The last line means I can omit {}? so let's go on:

irb(main):155:0> hash = "A"=>1 , "B"=>2
SyntaxError: compile error
(irb):155: parse error, unexpected tASSOC, expecting $
hash = "A"=>1 , "B"=>2
            ^
        from (irb):155
        from :0
irb(main):156:0>

Hmm why [ "A"=>1 , "B"=>2 ] silently produce [{"A"=>1, "B"=>2}] ?

my 2c,
Florent,

Florent Guiliani 작성:

for reading:
irb(main):152:0> hash["A"]
=> 1

If you go wrong:
irb(main):156:0> hash{"A"}
=> 537984250
irb(main):154:0> hash = [ "A"=>1 , "B"=>2 ]
=> [{"A"=>1, "B"=>2}]

I would prefer an error or warning. The last line means I can omit {}?

Yes, you can omit {} for method argument in some condition.

hash = [ "A"=>1 , "B"=>2 ]
hash = Array.new << {"A"=>1 , "B"=>2}
hash = Array.new.push("A"=>1, "B"=>2)

Third form is regular. Think first and second case is special thing.

quote in PickAxe book(Programming Ruby):

Collecting Hash Arguments

...snip

You can place key => value pairs in an argument list, as
long as they follow any normal arguments and precede any array and block arguments.
All these pairs will be collected into a single hash and passed as one argument to the
method.

I think this feature make method call interface more freely.

method_call :one => something
method_call :two => another
method_call :one => something, :two => another
method_call :two => another, :one => something, :three => this

Trans wrote:
Correction:

I don't [and] most of us [don't] use those shorcuts, prefering to alwasy use #{...}
notation:

  puts "test #{@@test}"
  puts "test #{@test}"
  puts "test #{test}"

Also, I might suggest that matz/ruby do away with those shortcuts.

T.

And many other objects, like String and Proc. This makes for great duck typing.

James Edward Gray II

···

On Oct 18, 2006, at 10:28 AM, Bira wrote:

As for the hashes, it just happens that is the name of the method
that retrieves a certain element from a collection. If you look at it
this way, it becomes quite logical for both collections to have the
same syntax.

Hal Fulton wrote:

Conflict with block syntax. You can't say hash {"A"} meaningfully.
In fact, I'm not certain why that returns an integer.

Huh? You must know. It's the #hash method:

irb(main):001:0> o = Object.new
=> #<Object:0xb7d06254>
irb(main):002:0> o.hash
=> -605540054
irb(main):003:0> o.hash { }
=> -605540054

Trans wrote:

Trans wrote:
Correction:

I don't [and] most of us [don't] use those shorcuts, prefering to alwasy use #{...}
notation:

puts "test #{@@test}"
puts "test #{@test}"
puts "test #{test}"

Also, I might suggest that matz/ruby do away with those shortcuts.

Absolutely not.

Hal

And stressing the, probably, obvious:

irb(main):001:0> hash
=> -605215560
irb(main):002:0> self.hash
=> -605215560

···

On 10/18/06, Trans <transfire@gmail.com> wrote:

Hal Fulton wrote:

> Conflict with block syntax. You can't say hash {"A"} meaningfully.
> In fact, I'm not certain why that returns an integer.

Huh? You must know. It's the #hash method:

irb(main):001:0> o = Object.new
=> #<Object:0xb7d06254>
irb(main):002:0> o.hash
=> -605540054
irb(main):003:0> o.hash { }
=> -605540054

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

Hal Fulton wrote:

Trans wrote:
> Trans wrote:
> Correction:
>
>
>>I don't [and] most of us [don't] use those shorcuts, prefering to alwasy use #{...}
>>notation:
>>
>> puts "test #{@@test}"
>> puts "test #{@test}"
>> puts "test #{test}"
>
>
> Also, I might suggest that matz/ruby do away with those shortcuts.

Absolutely not.

Becaue you like extraneous notations that are rarely used and
subsequently create less readiable code?

T.

Trans wrote:

Hal Fulton wrote:
> Trans wrote:
> > Also, I might suggest that matz/ruby do away with those shortcuts.
>
> Absolutely not.

Becaue you like extraneous notations that are rarely used and
subsequently create less readiable code?

What evidence do you have to support the claim that they are rarely
used? Also, would you concede that "less readable code" is a subjective
criticism?

I personally use #@foo for every (as far as I know) instance variable
I've included as a part of my own string interpolation code.

I've never used it or new it existed and have now taken a note to
watch out for it should I ever have #@something in a "string".

Not that I know enough about ruby or development in general to speak
on it's validity, however I would be interest in seeing the actual
lines of code in the ruby source that checks the #@something syntax.
Could someone share it if it's not too much trouble?

Is the ruby logic something like this?
    if string contains "#@" and the text after the "@" (with some
delimiter) prefixed with an "@" is a variable, interpret it??

I cant see anyway this is what's being done because it seems horible
lol.. What does it actually do? Please share

···

On 10/18/06, Phrogz <gavin@refinery.com> wrote:

Trans wrote:
> Hal Fulton wrote:
> > Trans wrote:
> > > Also, I might suggest that matz/ruby do away with those shortcuts.
> >
> > Absolutely not.
>
> Becaue you like extraneous notations that are rarely used and
> subsequently create less readiable code?

What evidence do you have to support the claim that they are rarely
used? Also, would you concede that "less readable code" is a subjective
criticism?

I personally use #@foo for every (as far as I know) instance variable
I've included as a part of my own string interpolation code.

Trans wrote:

Hal Fulton wrote:
> Trans wrote:
> > Also, I might suggest that matz/ruby do away with those shortcuts.
>
> Absolutely not.

Becaue you like extraneous notations that are rarely used and
subsequently create less readiable code?

What evidence do you have to support the claim that they are rarely
used? Also, would you concede that "less readable code" is a subjective
criticism?

I personally use #@foo for every (as far as I know) instance variable
I've included as a part of my own string interpolation code.

Me too. Indeed, I find it more readable, personally.

Or at least, perfectly readable, and less cluttered.

Regards,

Bill

···

From: "Phrogz" <gavin@refinery.com>