OK... :) question about hash and array literals

H

Hal Fulton

It has always bothered me a little that [...] and {...} do not
call Array.new and Hash.new respectively.

I assume this is handled closer to parse time, for speed?

Is there a method that does get called (I think not), or could
in theory such a thing be implemented?

Example:

class Hash
def Hash.literal(*pairs)
pairs.each do |pair|
k, v = pair
puts "Adding key #{k}, value #{v}"
end
super # or whatever
end
end

x = {1=>2, 3=>4} # Output: Adding key 1, value 2
# Adding key 3, value 4

And yes, this is related again to my wanting an ordered arbitrarily
indexable collection with a convenient literal notation.

Just curious...

Hal
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: OK... :) question about hash and array literals"

|Is there a method that does get called (I think not), or could
|in theory such a thing be implemented?

Not planned, just because changing semantics of literals are too
dangerous, as dangerous as macros for my eyes.

matz.

p.s.
I'm thinking of preserving Hash order by not re-implement it by using
Tree or something, but by saving key order information along with hash
tables.
 
R

Robert Klemme

Hal Fulton said:
It has always bothered me a little that [...] and {...} do not
call Array.new and Hash.new respectively.

I assume this is handled closer to parse time, for speed?

Is there a method that does get called (I think not), or could
in theory such a thing be implemented?

Example:

class Hash
def Hash.literal(*pairs)
pairs.each do |pair|
k, v = pair
puts "Adding key #{k}, value #{v}"
end
super # or whatever
end
end

x = {1=>2, 3=>4} # Output: Adding key 1, value 2
# Adding key 3, value 4

And yes, this is related again to my wanting an ordered arbitrarily
indexable collection with a convenient literal notation.

Even if a ordered map would be added you would not want to change literals
default behavior. Too much code depends on this. I remember, we had a
similar discussion with String literals a while ago. See also my post in
the other thread.

Kind regards

robert
 
D

David A. Black

Hi --

Hi,

In message "Re: OK... :) question about hash and array literals"

|Is there a method that does get called (I think not), or could
|in theory such a thing be implemented?

Not planned, just because changing semantics of literals are too
dangerous, as dangerous as macros for my eyes.

This is just a thought (not even an "idea" :) but what about a
%-style constructor:

%H{ k1 => v1, k2 => v2, ... }

or something.


David
 
G

gabriele renzi

David A. Black ha scritto:
Hi --




This is just a thought (not even an "idea" :) but what about a
%-style constructor:

%H{ k1 => v1, k2 => v2, ... }

please no.
This is just my very little unvaluable opinion, but %-stuff literals are
one of the few things I don't like about ruby.
Nothing is telling me what they mean, It's something a user can't have
control over and there are subtle differencies beetween one and another
that are just... well.. _too_ subtle.


But as I write I'm getting the idea you're suggesting overridable %
constructors? If that is the suggestion.. well, interesting :)
 
D

David A. Black

Hi --

David A. Black ha scritto:


please no.
This is just my very little unvaluable opinion, but %-stuff literals are
one of the few things I don't like about ruby.
Nothing is telling me what they mean, It's something a user can't have
control over and there are subtle differencies beetween one and another
that are just... well.. _too_ subtle.
But as I write I'm getting the idea you're suggesting overridable %
constructors? If that is the suggestion.. well, interesting :)

I wasn't really suggesting anything concretely -- just looking for a
direction to go in to solve Hal's problem about no available literal
syntax. I think user-defined %-notation is probably impossible, since
any given notation could be defined by multiple libraries and
conflict.


David
 
G

gabriele renzi

David A. Black ha scritto:

I wasn't really suggesting anything concretely -- just looking for a
direction to go in to solve Hal's problem about no available literal
syntax. I think user-defined %-notation is probably impossible, since
any given notation could be defined by multiple libraries and
conflict.


David

yes, but no more than it is possible to have two classes with the same
name or two methods with the same name in Kernel.
If %something{blabla} worked like, say, a call to
PercentLiterals.something('blabla') (but somewhat done at compile time)
it could provide ri-able documentation, an extensible system, and
possibly, with time, the death of q/Q/w/W//s/x/.
Yeah, I really dislike them, sorry :)
 
D

David A. Black

David A. Black ha scritto:



yes, but no more than it is possible to have two classes with the same
name or two methods with the same name in Kernel.

Yes -- this is why it's usually bad to add methods to Kernel, unless
you're sure you're standalone.


David
 
P

Peter

But as I write I'm getting the idea you're suggesting overridable %
constructors? If that is the suggestion.. well, interesting :)

Maybe this is a good moment to bring this up: user defined % literals. A
way to define your own % literals or redefine existing ones. It is also
possible to have your own private redefinition of a literal thus avoiding
the problem of breaking other people's code. The proposal can be found
here:

http://www.rubygarden.org/ruby?UserDefinedLiterals

and as of today also at RCRchive:

http://rcrchive.net/rcr/RCR/RCR279

Peter
 
H

Hal Fulton

David said:
This is just a thought (not even an "idea" :) but what about a
%-style constructor:

%H{ k1 => v1, k2 => v2, ... }

or something.

Good idea, though I shy away from changing syntax more than I
shy away from changing and adding classes.

I was thinking something similar, now that you mention it: An array-like
notation with hash-like arrows inside:

x = {1=>2, 3=>4} # hash
y = [3,4] # array
z = [1=>2, 3=>4] # ordered association

Is this reasonable at all? Matz??


Hal
 
H

Hal Fulton

Yukihiro said:
Hi,

In message "Re: OK... :) question about hash and array literals"

|Is there a method that does get called (I think not), or could
|in theory such a thing be implemented?

Not planned, just because changing semantics of literals are too
dangerous, as dangerous as macros for my eyes.

matz.

p.s.
I'm thinking of preserving Hash order by not re-implement it by using
Tree or something, but by saving key order information along with hash
tables.


Yes, that is what I was thinking. That would also be the smallest impact
on the internals.

However, if order in literals is irrelevant, then hashes are not truly
ordered entities, are they?

See my other post about a [=>] notation... not an ideal solution perhaps,
but does preserve hash literals as they are.


Hal
 
T

ts

H> z = [1=>2, 3=>4] # ordered association

This is a nice syntax, and ruby really like it :)

svg% ruby -e 'p [1=>2, 3=>4]'
[{1=>2, 3=>4}]
svg%



Guy Decoux
 
H

Hal Fulton

ts said:
H> z = [1=>2, 3=>4] # ordered association

This is a nice syntax, and ruby really like it :)

svg% ruby -e 'p [1=>2, 3=>4]'
[{1=>2, 3=>4}]
svg%

Haha... but I would like to combine its love of the
syntax with a love of a new semantics. :)


Hal
 
P

Patrick May

Hello,

My main use for using ordered hashes is to express repeated regexp
string transformations. For example, in php I use this series of
regexp's to clean up html spacing:

foreach( array( '/\n|\f|\r/' => " ",
'/\s+/' => " ",
'/\s*<\/p>/i' => "</p>",
'/<p><(&nbsp;)?\/p>/i' => "",
'/<p>/i' => "\n\n<p>",
'/<p>$/i' => "", ) as $p => $r ) {
$string = preg_replace( $p, $r, $string );
}

There are of course other uses, but has been a real handy one for me.

Cheers,

Patrick
 
R

Robert Klemme

Patrick May said:
Hello,

My main use for using ordered hashes is to express repeated regexp string
transformations. For example, in php I use this series of regexp's to
clean up html spacing:

foreach( array( '/\n|\f|\r/' => " ",
'/\s+/' => " ",
'/\s*<\/p>/i' => "</p>",
'/<p><(&nbsp;)?\/p>/i' => "",
'/<p>/i' => "\n\n<p>",
'/<p>$/i' => "", ) as $p => $r ) {
$string = preg_replace( $p, $r, $string );
}

There are of course other uses, but has been a real handy one for me.

In this case nested arrays are sufficient since you don't need efficient
lookup. The only access is iteration as far as I can see. Example:

transformations = [
[/foo/, "bar"],
[/baz/, "xxx"],
[/\s+/, " "],
]

text = "xxx foo ddddd bar bazsiud"

transformations.each {|rx, repl| text.gsub!(rx, repl) }

Kind regards

robert
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: OK... :) question about hash and array literals"

|However, if order in literals is irrelevant, then hashes are not truly
|ordered entities, are they?

My opinion is preserving order reduces some "pitfalls". Reducing
pitfalls is a good thing. To be honest, I don't care whether Hash
being "true" ordered entity or not.

matz.
 
H

Hal Fulton

Yukihiro said:
Hi,

In message "Re: OK... :) question about hash and array literals"

|However, if order in literals is irrelevant, then hashes are not truly
|ordered entities, are they?

My opinion is preserving order reduces some "pitfalls". Reducing
pitfalls is a good thing. To be honest, I don't care whether Hash
being "true" ordered entity or not.

I defer to your judgment of course.

But a large part of my desire for an ordered collection of this nature
is the desire to write ordered literals.

Arrays and hashes in Ruby would not be nearly so convenient and clear
if one had to write:

arr = Array.new(3,5,7,9,11)
hsh = Hash[1,2,3,6,9,12)

If a Hash object preserved order, but a literal did not guarantee an order --
then to preserve the order with literals, we would have to do something like:

hash = {1=>2}.update(3=>4).update(5=>6)

instead of just

hash = {1=>2, 3=>4, 5=>6}

Is it a possible option to change the semantics of [x=>y] ?

h1 = {1=>2, 3=>4} # order not guaranteed
h2 = [1=>2, 3=>4] # order guaranteed

I realize (now) that [x=>y] is currently an array with a
single element which is a hash.


Hal
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: OK... :) question about hash and array literals"

|Is it a possible option to change the semantics of [x=>y] ?
|
| h1 = {1=>2, 3=>4} # order not guaranteed
| h2 = [1=>2, 3=>4] # order guaranteed
|
|I realize (now) that [x=>y] is currently an array with a
|single element which is a hash.

Are there any reason to make hash literals not to guarantee order?
I thought

h = {1=>2, 3=>4}

will preserve the order, when ordering is implemented.

matz.
 
H

Hal Fulton

Yukihiro said:
Are there any reason to make hash literals not to guarantee order?
I thought

h = {1=>2, 3=>4}

will preserve the order, when ordering is implemented.

Oh! I misunderstood completely, then.

My original understanding was that

{1=>2, 3=>4} == {3=>4, 1=>2}

implied that order was not preserved in literals.



Hal
 
B

Bill Guindon

Oh! I misunderstood completely, then.

My original understanding was that

{1=>2, 3=>4} == {3=>4, 1=>2}

implied that order was not preserved in literals.

It would depend on what the ordering is used for, no?
If ordering is only used to feed 'next', then the compare above would
still be true.

Personally, I'd like it to remember the order you added things in, use
that ordering when iterating through the hash, and _optionally_ use it
for compares.

Something like...
{1=>2, 3=>4} == {3=>4, 1=>2}
{1=>2, 3=>4}.ordered != {3=>4, 1=>2}.ordered
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top