--- "David A. Black" <dblack / wobblini.net> wrote:

> On Fri, 26 Aug 2005, Eric Mahurin wrote:
> 
> > --- "David A. Black" <dblack / wobblini.net> wrote:
> >
> >>> The klass.from_s(str) form also offers a little more
> power.
> >>  If
> >>> you are dealing with an arbitrary class (possibly of
> >> another
> >>> object) and you want to convert a String to an object of
> >> that
> >>> class, you just call the from_s method of that class. 
> You
> >>> don't have to go figure out what the right String#to_*
> >> method
> >>> to call is based on the class (and violate duck typing).
> >>
> >> Duck typing is irrelevant here.
> >
> > I think an example is needed to demonstrate my point.  Say
> you
> > have a command line parser where you want to convert
> options
> > from String to the relavent class.  Somewhere in the
> > specification, you may specify the class that you want the
> > option to be.  With the String#to_* methods, you have to do
> > something like this:
> >
> > def parse_option(klass,option)
> >  if klass.equal?(String)
> >    option
> >  elsif klass.equal?(Integer)
> >    option.to_i
> >  elsif klass.equal?(Float)
> >    option.to_f
> >  else
> >    raise("can't convert #{option} to #{klass}")
> >  end
> > end
> >
> > With klass.from_s(str) methods, here is what you get:
> >
> > def parse_option(klass,option)
> >  klass.from_s(option)
> > end
> >
> > Which is duck-typed?
> 
> Neither of them would I include in, say, an essay, on duck
> typing, not
> because they "violate" it (it's not a rule) but because it's
> not
> relevant.  Once you're passing class names around and doing
> explicit
> conversions based on class, that's what you're doing, and you
> might as
> well embrace it.

I'd disagree.  Even if you are passing classes around you
should be able to apply duck typing if you have the right
infrastructure.  The class just has to respond to the right
methods as opposed to the object.

> In the case of your example, I would probably do it like
> this:
> 
>    def parse_option(option)
>      #...
>    end
> 
>    parse_option(3)
>    parse_option(str.to_f)
>    parse_option(MyClass.from_s(str))  # if you must :-)
> 
> etc. -- and then you can duck-type the incoming argument all
> you like
> without having to convert it.  It's very cumbersome to have a
> method
> whose arguments have to be: an object, and a class which
> responds to
> from_s and whose from_s method takes objects of the class of
> *this*
> object as arguments....  Better to do it before you call the
> method.

Let's make a class out of this - an option spec:

class Option
  def initialize(name,required=false,klass=String)
    @name = name
    @required = required
    @klass = klass
  end
  ...
  def parse_option_arg(arg)
    @klass.from_s(arg)
  end
end

So, when you are describing the command line, you might give it
a list of these option specs:

Option.new("n",true,Integer),
Option.new("ratio",true,Float),
Option.new("f",true,File), # File#from_s(str) will open a File

Then when you have a command line like this:

-n 4 -ratio 0.75 -f xyz.txt

it could easily create objects appropriate for each option.



		
____________________________________________________
Start your day with Yahoo! - make it your home page 
http://www.yahoo.com/r/hs