Feature #9552
closed
Added by Anonymous almost 10 years ago.
Updated over 9 years ago.
Description
I would like to beg for map!
directive in Module
. I can imitate it with this code:
class Module
def map! **hash, &block
hash.each_pair { |mapped_method_symbol, original_method_symbol|
define_method mapped_method_symbol do |*args, &b|
block.( send original_method_symbol, *args, &b )
end
}
end
end
And then
class Foo; attr_accessor :name end
class Bar; attr_accessor :name end
class Baz; attr_accessor :name end
class FooBarBazCollection < Array
def foos; select { |e| e.is_a? Place } end
def bars; select { |e| e.is_a? Transition } end
def bazs; select { |e| e.is_a? Arc } end
map! fn: :foos, barn: :bars, bazn: :bazs do |retval| retval.map &:name end
end
I solemnly declare that I have encountered this pattern in my work on Petri net gem sufficiently many times to warrant this meta approach. The above method #map!
is not perfect, because it makes the "mapped" methods more omnivorous -- accepting even such sets of arguments, for which the originals returned ArgumentError
. I do not know how to solve this without asking for a core-level solution.
Core-level syntax might be similar to that of alias
,
class FooBarBazCollection
map! fn foos, barn bar, bazn bazs do |retval| retval.map &:name end
end
Another approach (without introducing a new keyword, which might be considered feature creep) would be to somehow make it possible for the built-in argument field validation of one method to be applied to another method. But that would probably require more introspection regarding the argument field than present day #arity
method offers, and also the possibility to unbind the argument field validation routine from a method and reuse it in another method. Then, perfect Module#map!
could be written and there would be no pressing need for new keywords.
I have created a new thread for this, #9553.
I failed to notice that Method#parameters
was already available. This makes it possible for me to implement my desired Module#map!
and other metaprogramming without asking for novel core syntax. The reasons supporting this feature suggestion are thus much weaker than I thougt.
- Status changed from Open to Feedback
I am not sure I understand your intention fully, but at least map! reminds us too much of enumerators.
I don't think there's a chance to add map! to module. Try another name.
Maybe some kind of method (or function) combination natation can help you.
Matz.
I apologize for late response. Again, I experienced that the method I'm proposing here has much practical use in my code. As for better name, I can think of:
#compose
--- weight: 3 -- as in functional composition
#apply
--- weight: 1 -- as in functional application
#chain
--- weight: 4 -- as in method chaining
#compose
is perhaps the most politically correct. While #apply
is not theoretically incorrect, the word too generic (much like using
) and overloads the metalanguage (English speaking about Ruby) too much. From these newly made up options, I personally prefer #chain
, which is sufficiently rare, expressive, and short to boot. I will be renaming Module#map!
to Module#chain
in my personal library, too -- thank you for forcing me to think.
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0