How to ducktype a Hash?

S

Sean O'Dell

Not necessarily. A database abstraction might act like a hash, but
wouldn't dump entire tables, which could contain tens of thousands of
records, as one big Ruby hash. That isn't positive identification.

Such an abstraction could give a lazy-loading Hash, as in

class DBAbstraction
def to_hash
Hash.new { |hash, key|
hash[key] = expensive_lookup(key)
}
end
end

So when you call #to_hash in the first place, it's empty. Each key
you call results in a calculation. All unbeknownst to the user of the
hash.

I don't see how this works. When you call to_hash, no arguments are provided,
so how could you use the key value there? I've also never seen the block
parameter to Hash.new. Not that this changes anything regarding positive
identification of a class' purpose, but it's very interesting. Is this all
new? My Pragmatic Programmer's Guide must already be far out of date.

Sean O'Dell
 
G

Gavin Sinclair

Not necessarily. A database abstraction might act like a hash, but
wouldn't dump entire tables, which could contain tens of thousands of
records, as one big Ruby hash. That isn't positive identification.

Such an abstraction could give a lazy-loading Hash, as in

class DBAbstraction
def to_hash
Hash.new { |hash, key|
hash[key] = expensive_lookup(key)
}
end
end

So when you call #to_hash in the first place, it's empty. Each key
you call results in a calculation. All unbeknownst to the user of the
hash.
I don't see how this works. When you call to_hash, no arguments are provided,
so how could you use the key value there? I've also never seen the block
parameter to Hash.new. Not that this changes anything regarding positive
identification of a class' purpose, but it's very interesting. Is this all
new? My Pragmatic Programmer's Guide must already be far out of date.

Try 'ri Hash.new'. All will be explained.

Your PragProgGuide certainly is out of date (so is everyone else's,
BTW :). It covers Ruby 1.6; Hash.new(&block) was introduced in
1.7/1.8.

Note that the above implementation of #to_hash would return a *new*
hash every time, thus losing the benefit of any precalculated values.
But you clearly get the point. And yes, it is interesting: a very
nice example of closures. It would perhaps be nice if all hash-like
classes offered this.

Gavin
 
S

Sean O'Dell

Not necessarily. A database abstraction might act like a hash, but
wouldn't dump entire tables, which could contain tens of thousands of
records, as one big Ruby hash. That isn't positive identification.

Such an abstraction could give a lazy-loading Hash, as in

class DBAbstraction
def to_hash
Hash.new { |hash, key|
hash[key] = expensive_lookup(key)
}
end
end

So when you call #to_hash in the first place, it's empty. Each key
you call results in a calculation. All unbeknownst to the user of the
hash.

I don't see how this works. When you call to_hash, no arguments are
provided, so how could you use the key value there? I've also never seen
the block parameter to Hash.new. Not that this changes anything
regarding positive identification of a class' purpose, but it's very
interesting. Is this all new? My Pragmatic Programmer's Guide must
already be far out of date.

Try 'ri Hash.new'. All will be explained.

No such command. It doesn't ship with Ruby? I installed ri as a gem, but it
installed something called Labyrinth. Anyway, interesting addition to Hash!

Sean O'Dell
 
J

Jean-Hugues ROBERT

Use the method #to_hash instead. All hash-like objects should be able to
give a hash-representation of themselves.

Rene

This makes a lot of sense to me. It seems to be symmetric
to to_str() too, which is good.

As a matter of fact, my rcr.rb has a to_hash() for Array:

# Have Array.to_h() return an ArrayAsHash.
# Please note that aa.to_h().to_a() == aa, which was the initial intend.
class Array
def to_h()
h = ArrayAsHash.new()
each_index do |ii| h[ii] = self[ii] end
return h
end
end

# What you get when converting an Array into a Hash, see Array##to_h()
# It is a Hash with keys that are integer indexes (from 0 up to size of hash).
class ArrayAsHash < Hash
def to_a()
super().sort_by { |(k,v)| k }.collect { |(k,v)| v }
# ToDo: There must be a faster solution to do that.
end
end

# Have Hash.to_a() return an HashAsArray instead of an Array.
# Besides the class there are no other difference.
class Hash
alias ruby_to_a to_a unless defined? ruby_to_a
# Returns an array of [key,value] pairs.
# Please note that h.to_a().to_h() == h for most purposes.
def to_a()
HashAsArray.new().replace( ruby_to_a())
end
# Returns self. Much like Array##to_a() does.
def to_h()
self
end
end

Yours,

JeanHuguesRobert
 
G

gabriele renzi

il Sun, 13 Jun 2004 12:05:47 +0900, Claus Spitzer
I suggested having a mix-in for , say, Input-like objects.
This is useful, imo, for two reasons:
it let's you build Input-like objects programmatically
it let's you strongly specify they're interface[2].

Now, this reminds me of aspect-oriented programming. Perhaps what is
wanted are some AOP tools for Ruby?

why does it? I'm not an AOP expert, but we have some degree of AOP in
ruby anyway, even if in Ruby2 that will be better. Anyway, If you will
I' d like to know more about this.

And if you're interested in AOP/defadvice this message from mauricio
fernandez may be of cool for you:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/97440
 
G

gabriele renzi

No such command. It doesn't ship with Ruby? I installed ri as a gem, but it
installed something called Labyrinth. Anyway, interesting addition to Hash!

it did not in the past, now it is included.
the Gems repository does not have ri, (I'd like it to be there anyway,
but ATM it is little useless, given that ri is in ruby's cvs), and it
used to do some silent pattern match on the requested gem, this is the
reason you goit labyrinth.

Anyway, you can look here:
http://www.ruby-doc.org/docs/rdoc/1.9/
 
G

gabriele renzi

il Sun, 13 Jun 2004 16:56:13 +0900, Jean-Hugues ROBERT

[ot]
I'm getting more convinced every day: would'nt be nice to have some
kind of global matrix of conversion bettween types and something on
the line of an 'as' operator?
 

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

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top