--0016364d21a74d484b0476fb344a
Content-Type: text/plain; charset=ISO-8859-1
Hi, here is my try:
module ObjectSpace
extend Enumerable
def each(mod il, &block)
if block_given?
if mod.is_a? Module
each_object(mod) { |o| block.call(o) }
else
each_object { |o| block.call(o) }
end
else
to_enum
end
end
module_function :each
(Enumerable.instance_methods-[:to_enum]).select { |m|
self.method(m).arity 0 }.each { |m|
instance_eval <<-STR
def #{m}(mod il, &block)
if mod.is_a? Module
objects o_enum.select { |o| o.is_a? mod }
else
objects o_enum
end
objects.send(:#{m}, &block)
end
STR
}
end
Some tests:
p ObjectSpace.each # #<Enumerator: ObjectSpace:each>
p ObjectSpace.map(Numeric) { |o| o } # [2.718281828459045,
3.141592653589793, ...]
p ObjectSpace.map(Class) { |c| c.name }.select { |o| o.to_s[0]<"E" } # ["Complex", "Binding", ...]
p ObjectSpace.select(Class) { |o| o.to_s[0]<"E" }.map { |c| c.name } # ["Complex", "Binding", ...]
I'm wondering which method should implement an arg. For this I used:
(Enumerable.instance_methods-[:to_enum]).select { |m| self.method(m).arity
0 }
# [:to_a, :sort, :sort_by, :find_all, :select, :reject, :collect, :map,
:partition, :group_by, :all?, :any?, :one?, :none?, :min, :max, :minmax,
:min_by, :max_by, :minmax_by, :reverse_each, :take_while, :drop_while]
I think the main interest is for each and map, maybe select because it looks
nice.
For the others, it seem more clear to me to do: ObjectSpace.select {|o|
o.is_a? mod}
Something I don't understand is why it seem impossible to modify each if
Enumerable is included
Cheers
--0016364d21a74d484b0476fb344a--