Hi -- On Sun, 29 Sep 2002, Massimiliano Mirra wrote: > On Sun, Sep 29, 2002 at 12:09:32PM +0900, dblack / candle.superlink.net wrote: > > Another thing people often point to that might deter people from > > learning a truly type-unchecked programming style is the wordiness of > > the most often-mentioned alternative, the "respond_to?" test: > > > > thing.action if thing.respond_to?(action) > > Do you really want your method to go on even if `thing' doesn't > respond to `action'? Similarly, would you do the following? > > thing.action if thing.is_a?(Thing) > > That would look as redundant (and dangerous). > > > This has the look and feel of duplicate, workaround code. Whereas > > this: > > > > raise ArgumentError unless obj.is_a?(Thing) > > Sorry David, I feel you're comparing apples and oranges here. :-) Yes, I don't think all my examples are synonymous with each other. > If verbs were always chosen for method names, this could be nice: > > obj.can?(:mkdir) > > And this wouldn't be too bad: > > def meth(obj) > continue if > obj.can?(:mkdir) and > obj.can?(:recurse) and > obj.can?(:list) > > > Or more concise: > > def meth(obj) > continue if obj.can?(:mkdir, :recurse, :list) I don't think the verb thing is a necessity. Maybe I'm just being influenced by the "Ich kann Deutsch" ("I can [speak] German") idiom. Actually this is all reminiscent of Franz Schubert's stock question, upon being introduced to or told about another person: "Kann er was?" (Can he do anything? i.e., is he good at anything?) :-) Anyway, just for fun, here's a little testbed. Ummmm, it just got less little. It expands modules and classes into their public instance methods, so you can do obj.can?(Enumerable). module Kernel def can?(*meths) x_meths = meths.map do |m| begin m.public_instance_methods rescue NameError m end end .flatten not x_meths.detect { |m| not respond_to?(m) } end def screen_for(*meths) if can?(*meths) yield true else false end end end class CanTest def meth(obj) raise NameError unless obj.can?(:split, :chomp) obj.split(//) end def screen_me(obj) obj.screen_for(:split, :chomp) do puts "OK, passed the screen" obj.split(//) end end def screen_for_Enum(obj) obj.screen_for(Enumerable) do puts "OK, passed the Enum screen" obj.each {|e| puts "Element: #{e}"} end end end c = CanTest.new puts c.meth("abc") begin puts c.meth([]); rescue NameError; puts "Didn't work with []"; end puts c.screen_me("abc") puts c.screen_for_Enum([1,2,3]) puts c.screen_for_Enum(3) David -- David Alan Black | Register for RubyConf 2002! home: dblack / candle.superlink.net | November 1-3 work: blackdav / shu.edu | Seattle, WA, USA Web: http://pirate.shu.edu/~blackdav | http://www.rubyconf.com