Assoc Class (Hash Pairs)

i’ve been thinking about posting this as an RCR.

i would really like to see hash pairs (associations) become real
objects. i think it would be a very powerful and useful construct. there
are number of things one could then do. The simpliest obviosuly being:

x = ‘a’=>1
y = ‘b’=>2

hash = { x, y }

ordered hashes also become a snap, implemented as arrays of these
associations:

ordhash = [ x, y ]

or, without the above x and y assignments, just

ordhash = [ ‘a’=>1 , ‘b’=>2 ]

this association class (Assoc?) would of course mixin the comparable
module.

the Assoc class becomes very useful when you start to build more comlex
structures (what i would like to use it for):

c = [ ‘a’=>1, ‘s’ ]

this is a very simple example, but without the Assoc you’d have to write
this as:

c = { ‘a’=>1, ‘s’=>nil }

adding a useless nil, or

c = [ [‘a’, 1], ‘s’ ]

whereby you have to use indexes on the association.

i’m sure there are other uses as well, and i think it may be possible
that such an Assoc class combined with arrays could ultimatly displace
regular hashes altogether.

···


~transami

This piques my interest, but I’m at a loss to see what one would DO with one
of these. Ie, you obviously see that some types of problems would be made
easier/cleaner by the use of this kind of data structure.

Can you give an example where having these would be helpful?

···

On Sun, 4 Aug 2002 04:05, you wrote:

i’ve been thinking about posting this as an RCR.

i would really like to see hash pairs (associations) become real
objects. i think it would be a very powerful and useful construct. there
are number of things one could then do. The simpliest obviosuly being:

x = ‘a’=>1
y = ‘b’=>2

hash = { x, y }

ordered hashes also become a snap, implemented as arrays of these
associations:

ordhash = [ x, y ]

or, without the above x and y assignments, just

ordhash = [ ‘a’=>1 , ‘b’=>2 ]

this association class (Assoc?) would of course mixin the comparable
module.

Hello –

i’ve been thinking about posting this as an RCR.

I think you can do everything you need in this area in Ruby as it
stands, though I may be wrong.

i would really like to see hash pairs (associations) become real
objects. i think it would be a very powerful and useful construct. there
are number of things one could then do. The simpliest obviosuly being:

x = ‘a’=>1
y = ‘b’=>2

hash = { x, y }

To me that means that key x has value y. I wouldn’t want to have to
figure out that { x, y } is going to blossom into { ‘a’, 1, ‘b’, 2 }
(if I’m understanding the idea correctly).

the Assoc class becomes very useful when you start to build more comlex
structures (what i would like to use it for):

c = [ ‘a’=>1, ‘s’ ]

this is a very simple example, but without the Assoc you’d have to write
this as:

c = { ‘a’=>1, ‘s’=>nil }

adding a useless nil, or

If it’s useless, don’t add it :slight_smile: The value for ‘s’ will default to
nil, unless your hash has a non-default default.

c = [ [‘a’, 1], ‘s’ ]

whereby you have to use indexes on the association.

Just curl your braces:

c = [ { ‘a’,1 }, ‘s’ ]

and you get something which I think does what you want.

i’m sure there are other uses as well, and i think it may be possible
that such an Assoc class combined with arrays could ultimatly displace
regular hashes altogether.

I don’t think what you’re describing, if I’m understanding it, is a
superset of regular hashes. But in any case – why would you want
something to displace hashes? The usefulness of hashes is pretty well
established. You can always add functionality to Ruby – it’s not a
zero-sum game :slight_smile:

David

···

On Sun, 4 Aug 2002, Tom Sawyer wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

i’ve been thinking about posting this as an RCR.

i would really like to see hash pairs (associations) become real
objects. i think it would be a very powerful and useful construct. there
are number of things one could then do. The simpliest obviosuly being:

x = ‘a’=>1
y = ‘b’=>2

hash = { x, y }

A pair is a real object; it’s called an array (with length=2).
Extensions often need to create such an object using rb_assoc_new (from
array.c):

VALUE
rb_assoc_new(car, cdr)
VALUE car, cdr;
{
VALUE ary;

  ary = rb_ary_new2(2);
  RARRAY(ary)->ptr[0] = car;
  RARRAY(ary)->ptr[1] = cdr;
  RARRAY(ary)->len = 2;

  return ary;

}

ordered hashes also become a snap, implemented as arrays of these
associations:

ordhash = [ x, y ]

In Ruby, this is done with an array of arrays:

x = [‘a’, 1]
y = [‘b’, 2]
ordhash = [ x, y ]
p ordhash.assoc(‘a’)[1] #=> 1

or, without the above x and y assignments, just

ordhash = [ ‘a’=>1 , ‘b’=>2 ]
this association class (Assoc?) would of course mixin the comparable
module.

This might be useful. But how would this comparison be done? Would it
compare keys or values? Or a combination?

the Assoc class becomes very useful when you start to build more comlex
structures (what i would like to use it for):

c = [ ‘a’=>1, ‘s’ ]

this is a very simple example, but without the Assoc you’d have to write
this as:

c = { ‘a’=>1, ‘s’=>nil }

I see no reason why Ruby should assume that if ‘s’ has a key but no
value associated with it that it should get nil. It would be MUCH more
useful to me to have the default be true, instead. I doubt there can be
a default that will please everyone.

If you create a hash, then elements with no keys get nil by default. So
what you have written is not too different from:

c = { ‘a’=> 1 }
p c[‘s’] #=> nil

except that iterating over the above structure produces a different
result.

adding a useless nil, or

c = [ [‘a’, 1], ‘s’ ]

whereby you have to use indexes on the association.

Here’s an option:

c = [ [‘a’, 1], ‘s’ ]
d = c.map { |x| Array === x ? x : [ x, nil ] }
e = Hash[*d]

You can put this into a function somewhere if you want to avoid writing
it over and over.

i’m sure there are other uses as well, and i think it may be possible
that such an Assoc class combined with arrays could ultimatly displace
regular hashes altogether.

Hashes have O(1) lookups, but are not ordered. An array of assocs has
O(n) lookups, but are ordered. Trees make a good compromise (more
complex, but ordered with O(log(n)) lookups), which would probably make
a better choice.

Paul

···

On Sun, Aug 04, 2002 at 03:05:49AM +0900, Tom Sawyer wrote:

i’ve been thinking about posting this as an RCR.

Interesting idea. Some comments…

i would really like to see hash pairs (associations) become real
objects. i think it would be a very powerful and useful construct. there
are number of things one could then do. The simpliest obviosuly being:

x = ‘a’=>1
y = ‘b’=>2

hash = { x, y }

Hmm. This doesn’t really accomplish anything except a simpler
syntax (for the last statement), does it? And what happens if
you put something into the braces that isn’t an Assoc object?

ordered hashes also become a snap, implemented as arrays of these
associations:

ordhash = [ x, y ]

Well, it’s ordered, all right; but is it really a hash
any more? E.g., could you still get this to work?

z = ordhash[‘a’] # equals 1

Not without changing the [] method of Array. And if you
change it in such a way, you’re making Array into Hash.

or, without the above x and y assignments, just

ordhash = [ ‘a’=>1 , ‘b’=>2 ]

Same comments.

I’m still open to being convinced this is useful,
though…

Hal

i recall having a need for it some time ago, but i don’t recall off hand
what that was. but the use i recently ran across was for building
complex hierachies (for gui models) where sometimes you have a "child"
object and some times you don’t:

complex_hierarchy = [ parent => child,
childless,
another_parent => [ subchildless,
subparent => subchild ]
]

without this, you either have to use hashes with extraneous nils, or
fall back to pure associative arrays.

in effect, i think i may be getting at a merger of hash and array, where
elements can have index => value associations, but others don’t.

so that’s my need. but the idea of associations in and of themselves
strikes me as if they may be useful on their own.

~transami

···

On Sat, 2002-08-03 at 16:19, Harry Ohlsen wrote:

On Sun, 4 Aug 2002 04:05, you wrote:

i’ve been thinking about posting this as an RCR.

i would really like to see hash pairs (associations) become real
objects. i think it would be a very powerful and useful construct. there
are number of things one could then do. The simpliest obviosuly being:

x = ‘a’=>1
y = ‘b’=>2

hash = { x, y }

ordered hashes also become a snap, implemented as arrays of these
associations:

ordhash = [ x, y ]

or, without the above x and y assignments, just

ordhash = [ ‘a’=>1 , ‘b’=>2 ]

this association class (Assoc?) would of course mixin the comparable
module.

This piques my interest, but I’m at a loss to see what one would DO with one
of these. Ie, you obviously see that some types of problems would be made
easier/cleaner by the use of this kind of data structure.

Can you give an example where having these would be helpful?


~transami

thanks david, that was very helpful. i had forgotten that hashes could
be designated with commas, although i find that notation lacking some
clarity. and the hash default helps too. so i can basically do what i
need with out extraneous code hanging about. awesome.

on the other hand i have this odd inclination toward everything being an
object in an OOPL. even hash pairs. call me crazy! :slight_smile:

···

On Sun, 2002-08-04 at 06:40, David Alan Black wrote:

I don’t think what you’re describing, if I’m understanding it, is a
superset of regular hashes. But in any case – why would you want
something to displace hashes? The usefulness of hashes is pretty well
established. You can always add functionality to Ruby – it’s not a
zero-sum game :slight_smile:


~transami

no, not exactly. it’s still array. you’d have to say:

z = ordhash[0][‘a’]

or

z = ordhash[0].value

although it may not be out of the question to give Array a little more
smarts to do what you are suggesting. then certainly this would supplant
the regualar Hash class.

also i have a notion that these associations may actually be useful on
their own.

a = ‘A’=>'The Letter A’
b = ‘B’=>'The Letter B’
c = ‘C’=>‘The Letter C’

puts a.index # --> A
puts b.value # --> The Letter B

puts a[‘A’] # --> The Letter A
puts c[‘The Letter C’] # --> C

but as for being especially useful? who knows what others might dream
up. i could use it for complex hierarchies. someone else might find
another use.

taking it a bit further, i realize i’m also leaning toward something
more. sort of an alternative to assingment:

a = 'A’
b = ‘The Letter A’

a => b

puts a.assoc # --> The Letter A

thus having a way to association objects to one another, sort of like
having varaible variable names.

just thinking out loud at this point.

···

On Sat, 2002-08-03 at 16:40, Hal E. Fulton wrote:

Well, it’s ordered, all right; but is it really a hash
any more? E.g., could you still get this to work?

z = ordhash[‘a’] # equals 1

Not without changing the [] method of Array. And if you
change it in such a way, you’re making Array into Hash.


~transami

This way, the parent won’t know it has a child, and the child won’t
know it has a parent. Is this intended? If so, try out this:

class Assoc
def Assoc.
new(*args)
end

def initialize(from, to nil)
	@from, @to = from, to
end
attr_reader :from, :to

end

class Object
def link(to)
Assoc[self, to]
end
end

complex_hierarchy = [ Assoc[parent, child],
childless,
another_parent.link([
subchildless,
Assoc[subparent, subchild]
])

Not as nice as a simple `=>’, but seems to do what you ask.

(I wonder, however, if `=>’ could be made into a method of Object.)

Massimiliano

···

On Sun, Aug 04, 2002 at 08:47:35AM +0900, Tom Sawyer wrote:

i recall having a need for it some time ago, but i don’t recall off hand
what that was. but the use i recently ran across was for building
complex hierachies (for gui models) where sometimes you have a "child"
object and some times you don’t:

complex_hierarchy = [ parent => child,
childless,
another_parent => [ subchildless,
subparent => subchild ]
]

without this, you either have to use hashes with extraneous nils, or
fall back to pure associative arrays.

Hi –

I don’t think what you’re describing, if I’m understanding it, is a
superset of regular hashes. But in any case – why would you want
something to displace hashes? The usefulness of hashes is pretty well
established. You can always add functionality to Ruby – it’s not a
zero-sum game :slight_smile:

thanks david, that was very helpful. i had forgotten that hashes could
be designated with commas, although i find that notation lacking some
clarity. and the hash default helps too. so i can basically do what i
need with out extraneous code hanging about. awesome.

on the other hand i have this odd inclination toward everything being an
object in an OOPL. even hash pairs. call me crazy! :slight_smile:

It’s an interesting thing to think about, in part because it raises
the question of what “everything” is. For example, an array is an
ordered list of elements, where each element can be of any type. So
– should there be an ArrayElement type? I tend to think of “hash
pair” as sort of like “array element” – I don’t mean I think of them
as the same construct, but rather that, in both cases, I take the
object-hood of the underlying elements to be sufficient (in terms of
"everything is an object"), together with the object-hood of the
containers themselves.

David

···

On Sun, 4 Aug 2002, Tom Sawyer wrote:

On Sun, 2002-08-04 at 06:40, David Alan Black wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Well, it’s ordered, all right; but is it really a hash
any more? E.g., could you still get this to work?

z = ordhash[‘a’] # equals 1

Not without changing the [] method of Array. And if you
change it in such a way, you’re making Array into Hash.

no, not exactly. it’s still array. you’d have to say:

z = ordhash[0][‘a’]

or

z = ordhash[0].value

Yes, but that’s my point: It’s not a hash any more. It’s
like an array of single-element hashes.

To find the value associated with key ‘a’, I’d have to
know that ‘a’ was in ordhash[0].

Someone yesterday (?) posted an interesting use of
Array#assoc… I think this is probably the “right” way to
implement an ordered hash… and I wish I had thought of
that two years ago.

a = ‘A’=>'The Letter A’
b = ‘B’=>'The Letter B’
c = ‘C’=>‘The Letter C’

puts a.index # --> A
puts b.value # --> The Letter B

puts a[‘A’] # --> The Letter A
puts c[‘The Letter C’] # --> C

Hmm. Maybe.

a = 'A’
b = ‘The Letter A’

a => b

puts a.assoc # --> The Letter A

thus having a way to association objects to one another, sort of like
having varaible variable names.

Incompatible with the earlier suggestion, of course, since
a => b would be a valid Assoc value.

just thinking out loud at this point.

Frequently a helpful thing!

Hal

···

----- Original Message -----
From: “Tom Sawyer” transami@transami.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Saturday, August 03, 2002 7:15 PM
Subject: Re: Assoc Class (Hash Pairs)

On Sat, 2002-08-03 at 16:40, Hal E. Fulton wrote:

z = ordhash[0][‘a’]

or

z = ordhash[0].value

although it may not be out of the question to give Array a little more
smarts to do what you are suggesting.

That would lead to ambiguity, e.g.:

z = { 1 => ‘bar’, ‘foo’ => String }

What will z[1] mean?

Think of Array as a special case of Hash, where keys are integers and
are set implicitely when an object is added. With a ordered hash you
have two keys, not one, and if you want to access values with the #[]
method, it has to know to which key you are referring.

c = ‘C’=>'The Letter C’
puts c[‘The Letter C’] # --> C

So are the associations you’re thinkin of bidirectional?

a = 'A’
b = ‘The Letter A’

a => b

puts a.assoc # --> The Letter A

Wouldn’t that be a.value, according to your examples above?

thus having a way to association objects to one another, sort of like
having varaible variable names.

You are thinking in terms of bidirectional links between objects.
Take a look at the ZigZag concept, you’ll find lots of food for
thought. :slight_smile:

Massimiliano

···

On Sun, Aug 04, 2002 at 09:15:12AM +0900, Tom Sawyer wrote:

i think i understand what your getting at.

but on particulars, there is such a thing as ArrayElement. it is called
Object. for an array’s elements are objects (100% O), while a hashes are
not. rather they are some sort of syntatical-construct-of-association
between two objects (nil-O)

boy i’m in a strnge mood this morning :slight_smile:

···

On Sun, 2002-08-04 at 07:38, David Alan Black wrote:

It’s an interesting thing to think about, in part because it raises
the question of what “everything” is. For example, an array is an
ordered list of elements, where each element can be of any type. So
– should there be an ArrayElement type? I tend to think of “hash
pair” as sort of like “array element” – I don’t mean I think of them
as the same construct, but rather that, in both cases, I take the
object-hood of the underlying elements to be sufficient (in terms of
"everything is an object"), together with the object-hood of the
containers themselves.

~transami

OK, Massimiliano, now you’ve done it – you’ve
mentioned ZigZag!

I’ve read about it, though I’m still trying to
assimilate it. It sounds like it’s just a
specialized form of a directed graph with a
few constraints on it.

Or is ZigZag the app itself? I thought it was
a kind of data structure…

Are there good practical uses for it, and has
anyone here done anything with it (especially
in Ruby)?

Hal

···

----- Original Message -----
From: “Massimiliano Mirra” list@NOSPAMchromatic-harp.com.web-hosting.com
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Saturday, August 03, 2002 8:38 PM
Subject: Re: Assoc Class (Hash Pairs)

You are thinking in terms of bidirectional links between objects.
Take a look at the ZigZag concept, you’ll find lots of food for
thought. :slight_smile:

i’ll take a look at this ZigZag. thanks.

inspired by you i threw this together. had to use ** instead of => (as
you can’t use that) and alias ** as ‘exp’ for the three classes it’s
used by. just a bit of fun:

class Assoc

include Comparable

attr_accessor :index, :value

def Assoc.
new(*args)
end

def initialize(index, value=nil)
@index = index
@value = value
end

def <=>(assoc)
return -1 if self.value < assoc.value
return 1 if self.value > assoc.value
return 0 if self.value == assoc.value
end

def reverse!
temp = @index
@index = @value
@value = temp
end

def to_s
return “#{index.to_s}#{value.to_s}” # ?
end

end

class Bignum
alias exp **
end

class Fixnum
alias exp **
end

class Float
alias exp **
end

class Object
def **(to)
Assoc[self, to]
end
end

complex_hierarchy = [ ‘parent’ ** ‘child’,
‘childless’,
‘another_parent’ ** [ ‘subchildless’,
‘subparent’ ** ‘subchild’
]
]

now dosen’t that look like a strange beast. :slight_smile:

~transami

···

On Sat, 2002-08-03 at 19:38, Massimiliano Mirra wrote:

On Sun, Aug 04, 2002 at 09:15:12AM +0900, Tom Sawyer wrote:

z = ordhash[0][‘a’]

or

z = ordhash[0].value

although it may not be out of the question to give Array a little more
smarts to do what you are suggesting.

That would lead to ambiguity, e.g.:

z = { 1 => ‘bar’, ‘foo’ => String }

What will z[1] mean?

Think of Array as a special case of Hash, where keys are integers and
are set implicitely when an object is added. With a ordered hash you
have two keys, not one, and if you want to access values with the #[]
method, it has to know to which key you are referring.

c = ‘C’=>'The Letter C’
puts c[‘The Letter C’] # --> C

So are the associations you’re thinkin of bidirectional?

a = 'A’
b = ‘The Letter A’

a => b

puts a.assoc # --> The Letter A

Wouldn’t that be a.value, according to your examples above?

thus having a way to association objects to one another, sort of like
having varaible variable names.

You are thinking in terms of bidirectional links between objects.
Take a look at the ZigZag concept, you’ll find lots of food for
thought. :slight_smile:

Massimiliano


~transami

Hi –

It’s an interesting thing to think about, in part because it raises
the question of what “everything” is. For example, an array is an
ordered list of elements, where each element can be of any type. So
– should there be an ArrayElement type? I tend to think of “hash
pair” as sort of like “array element” – I don’t mean I think of them
as the same construct, but rather that, in both cases, I take the
object-hood of the underlying elements to be sufficient (in terms of
"everything is an object"), together with the object-hood of the
containers themselves.

i think i understand what your getting at.

but on particulars, there is such a thing as ArrayElement. it is called
Object. for an array’s elements are objects (100% O), while a hashes are
not. rather they are some sort of syntatical-construct-of-association
between two objects (nil-O)

You could argue that an array is basically a hash whose keys are
constrained to be Integers. So that would leave you needing a
AssocWhereKeyIsAlwaysAnInteger class, I guess :slight_smile:

Another way to think of it is that hashes are just arrays which have
the ability to return odd-numbered elements from a query based on the
previous even-numbered element:

class MyHash < Array
alias :oldget :[]

def [](k)
  ind = (0...size).detect {|i| i % 2 == 0 and self.at(i) == k}
  ind ||= size
  self.oldget(ind+1)
end

end

m = MyHash.new.concat %w{ a b c d e f }
p m[‘c’] # => “d”

Dinky example, but you see the point: if arrays are OK, and methods
are OK, then if hashes can be defined in terms of arrays and their
methods [Q: is this CS’ly sound?], then hashes are OK.

David

···

On Sun, 4 Aug 2002, Tom Sawyer wrote:

On Sun, 2002-08-04 at 07:38, David Alan Black wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hashes don’t have “elements”. They map Objects to Objects. That is their
interface; that is what they are. “Map” is an English-language term used in
documentation to describe the function of a Hash. You can iterate over the
"mappings", and you are given the Objects contained therein.

Hashes are no more, and no less, object-oriented than Arrays.

Cheers,
Gavin

···

----- Original Message -----
From: “Tom Sawyer” transami@transami.net

i think i understand what your getting at.

but on particulars, there is such a thing as ArrayElement. it is called
Object. for an array’s elements are objects (100% O), while a hashes are
not. rather they are some sort of syntatical-construct-of-association
between two objects (nil-O)

Generally the right way to implement an ordered “hash” is with a tree.
Sometimes, depending on why you need it to be ordered, an ordinary hash,
where he members are lists is a better choice.

I suppose the questions that determine this are:

  1. Why are you specifying a hash? Is it just for the random access
    capability, or is there some other reason (e.g., the ability to extract an
    access code).
  2. Do you need the access key to be sorted, or are you maintaining a list of
    entities with the same access key?
  3. How big is this thing, anyway? Are you planning to store it on disk, and
    only roll in the needed parts, or is it RAM resident? (This can make a tree
    the right answer no matter how the other questions are answered.)

Under the normal interpretations, an “ordered hash” is a contradiction in
terms, so I’m guessing that you probably have some other meaning, like one
that keeps an ordered list of members with the same key value.

···

On Saturday 03 August 2002 17:45, you wrote:

----- Original Message -----

Yes, but that’s my point: It’s not a hash any more. It’s
like an array of single-element hashes.

To find the value associated with key ‘a’, I’d have to
know that ‘a’ was in ordhash[0].

Someone yesterday (?) posted an interesting use of
Array#assoc… I think this is probably the “right” way to
implement an ordered hash… and I wish I had thought of
that two years ago.

Hal

You are thinking in terms of bidirectional links between objects.
Take a look at the ZigZag concept, you’ll find lots of food for
thought. :slight_smile:

OK, Massimiliano, now you’ve done it – you’ve
mentioned ZigZag!

Sounds like you’d been waiting for this. :slight_smile:

I’ve read about it, though I’m still trying to
assimilate it. It sounds like it’s just a
specialized form of a directed graph with a
few constraints on it.

From what I’ve gathered, I might add: a graph where links are
organized in separate sets, each set with a different meaning or
domain.

Or is ZigZag the app itself? I thought it was
a kind of data structure…

It is (or at least I don’t know of any homonym or eponym application).

Are there good practical uses for it,

Quoting myself from 42686:

> > I just could not figure out *any* case where a ZigZag would help > > me...

The case brought up in this thread, for instance. When a different
way of navigating through the database is needed, a new web of links
is created instead of reorganizing the database.

Navigating in a ZigZag is not quite something you can relate
to any other navigational experience you may have had before.

Why, it’s relatively easy. Think of browsing a hypertext by theme:
load it, choose Computer Science'' from a menu, and the words that get activated as links are those that lead to documents in theComputer Science’’ web; choose Politics'' and the words that get activated are those that lead to documents in thePolitics’’ web.
In other words, each node (the document) of the web can have more
than just one group of ways out (links to other documents).

and has
anyone here done anything with it (especially
in Ruby)?

Experimenting with it has been on my todo list not from my Ruby day #0
but quite close to that. I think I’ve applied something like that in
my tiny spreadsheet tool `ecalc’: it lets you define relations between
numeric data in form of equations, and then choose what data insert
and what data calculate on the fly, instead of hardcoding formulas
into cells; a number of calculations can be put in sequence and named,
then a sequence can be called an calculated at once. Three and
multi-dimensional spreadsheets is something else I’d like to explore.

Massimiliano

···

On Sun, Aug 04, 2002 at 11:13:48AM +0900, Hal E. Fulton wrote:

Gavin Sinclair wrote:

From: “Tom Sawyer” transami@transami.net

i think i understand what your getting at.

but on particulars, there is such a thing as ArrayElement. it is called
Object. for an array’s elements are objects (100% O), while a hashes are
not. rather they are some sort of syntatical-construct-of-association
between two objects (nil-O)

Hashes don’t have “elements”. They map Objects to Objects. That is their
interface; that is what they are. “Map” is an English-language term used in
documentation to describe the function of a Hash. You can iterate over the
"mappings", and you are given the Objects contained therein.

Hashes are no more, and no less, object-oriented than Arrays.

Hashes do have elements in one sense:

h = {:a=>1, :b=>2}
h.entries # ==> [[:b, 2], [:a, 1]]

Or in the sense that you get ordered pairs when you iterate:

h.each { |k,v| … }

The ordered pairs don’t “remember” that they came from a hash, but then
neither do the array elements you get when you iterate over an array.

Syntax preferences aside, why isn’t an ordered pair good enough to
represent an association between two objects? It’s got just enough
information (a first and a second element), and it uses the most
efficient construct for the job. What more could you want?

If you really want the association to remember that it came from a hash,
and to “know” that the first element is a key and the second is the
value associated with it, you can use a hash with one entry:

class Hash
def each_assoc
each { |k, v| yield({k => v}) }
end
end

h = {:a=>1, :b=>2, :c=>3}

h.each_assoc { |assoc| p assoc }

class Hash
def select_subhash
result = {}
each_assoc { |a| result.update a if yield a }
result
end

 def value
   if size == 1
     values[0]
   else
     raise "No unique value"
   end
 end

end

k = h.select_subhash { |a| a.value >= 2 }

p k # ==> {:b=>2, :c=>3}

This is definitely not as efficient as ordered pairs, but maybe it’s
clearer if you really want to think in terms of associations.

···

----- Original Message -----