so i tried my hand at including count in Enumberable and “normalizing”
String and Hash accordingly. take a look at the attached script to see
how the current design is a tad odd, versus how these changes effect it.
module Enumerable
def count(c)
self.select { |i| i == c }.length
end
end
class String
alias contains count
remove_method :count
def each
each_byte { |c| yield c.chr }
end
end
class Hash
remove_method :include?
each is synonomous with each_value, not each_pair
alias each each_value
include key shoud be the primary method, has_key the alias but…
alias include_key? has_key?
ditto for value
alias include_value? has_value?
def include_pair?
# detect_pair …?.. now we start getting bushwacked
end
end
for String, #conatins will do what #count use to. i also redefined #each
to be each character, so then one would need to use use #each_line for
what #each used to mean (we could have just redefined what record
seperator ‘’ means, but would require $/ take regexps to compensate for
what ‘’ used to mean)
Hash is seriously inept at being normalized, as #include? should be
synonomous with has_value? and #count? should count on values. thus
#each needs to mean #each_value. trying to “normalize” Hash leads to
filling it with all sorts of methods: #detect_key, #detect_pair,
#count_key, #count_pair…etc." This all stems from the fact that Hash
isn’t really Enumberable. #each_with_index, for instance, is
meaningless, since a Hash is unordered, and the components of a Hash,
the pairs (x=>y) aren’t true objects in themselves.
for starters, anaylizing this in depth has led me to beleive that
Enumberable itself really is a intersection of two different types of
mixins. On the one hand everthing realated to #each partakes of their
own mixin called, say, Iterable. then the methods involving <=> (and ==
actually) would be left in Enumerable which also mixes-in Iterable. thus
hash is Iterable, but it is not Enumberable. this distinction would help
clear up “degeneration”, and the seperation could be useful elsewhere,
perhaps in Set, for instance.
but then there is the consideratin that x=>y, the Hash pairs may best
symbolize real objects, x=>y being the literal form. actually it is odd
that they don’t with ruby being 100% OO. is there any other such thing
in ruby? having the hash pairs as objects would actually make ordered
hashes pretty easy to make: [ x1=>y1, x2=>y2, … ] they are just arrays
of these pairs, and in fact may be capable of replacing Hash
altogether.(?)
class HashPair
attr_reader :index, :value
def initialize
@index
@value
end
… whatever methods make sense
end
HashPair may not be the best name. what do you call them? but you get
the idea. i’m very interested on hearing your thoughts on this.
~transami
t2.rb (2 KB)
···
On Sun, 2002-07-14 at 09:34, Christoph wrote:
-----Original Message-----
From: Philipp Meier [mailto:meier@meisterbohne.de]
Sent: Sunday, July 14, 2002 5:20 PM
To: ruby-talk ML
Subject: Re: hey! where’s #count?
On Sun, Jul 14, 2002 at 11:41:55PM +0900, Christoph wrote:
The problem is that some Enumerable classes like the Hash class or
a Set class (see for example rough/lib/set.rb - OT I am not sure why
this implementation doesn’t include Comparable) don’t know the
about the idea of multiple occurrences consequently you would
optimize #count to
def count(c)
each {|e| return 1 if e == c }
return 0
end
which is sort of an indication (to me) that #count doesn’t really
into
Enumerable …
Considering Enumerables like Set or Hash as a degenerated Enumerable I
find #count makes sense in Enumberable. Hash or Set can easily provide
optimized versions of #count. It like find for a sorted list which can
True - I guess my point was that the Hash/Set degeneration is so
common, that it is hard to speak(write) about “degeneration”.
/Christoph
–
~transami
(") dobee dobee do…
\v/
^ ^