Honoring #to_ary and such

Well, for about the first time I am writing a library that has to be
very strict about types. Per the usual I am testing types with `case`,
e.g.

    def foo=(foo)
     @foo = \
       case foo
       when Array
          foo
       when String
          [foo]
       else
         raise
       end
    end

Now as I do this it occurs to me, shouldn't I also honor anything that
responds_to?(:to_ary) as an Array? And if so, what's the "usual" way
to handle it then?

It depends. Do you want to? I suppose the only disadvantage would be
the cost of an object possibly creating a new array when to_ary is
invoked.

It might be worth letting the user decide with a second `force =
false` parameter.

I am also wondering, what makes a String special here as opposed to a
Fixnum or any other object?

···

On Fri, Jun 24, 2011 at 3:38 PM, Intransition <transfire@gmail.com> wrote:

Well, for about the first time I am writing a library that has to be
very strict about types. Per the usual I am testing types with `case`,
e.g.

def foo=(foo)
@foo = \
case foo
when Array
foo
when String
[foo]
else
raise
end
end

Now as I do this it occurs to me, shouldn't I also honor anything that
responds_to?(:to_ary) as an Array? And if so, what's the "usual" way
to handle it then?

def foo= foo
  @foo = Array(foo)
end

···

On Jun 24, 2011, at 12:38 , Intransition wrote:

Well, for about the first time I am writing a library that has to be
very strict about types. Per the usual I am testing types with `case`,
e.g.

   def foo=(foo)
    @foo = \
      case foo
      when Array
         foo
      when String
         [foo]
      else
        raise
      end
   end

Now as I do this it occurs to me, shouldn't I also honor anything that
responds_to?(:to_ary) as an Array? And if so, what's the "usual" way
to handle it then?

I am interested to know why it has to be strict about types?

···

On Sat, Jun 25, 2011 at 7:38 AM, Intransition <transfire@gmail.com> wrote:

Well, for about the first time I am writing a library that has to be
very strict about types. Per the usual I am testing types with `case`,

It depends. Do you want to? I suppose the only disadvantage would be
the cost of an object possibly creating a new array when to_ary is
invoked.

No, I don't really :wink: But... I've always been under the impression
that something that responds to #to_ary should be treated as such.
Thanks to duck-typing I've never really had to give it much thought
before.

It might be worth letting the user decide with a second `force =
false` parameter.

I am also wondering, what makes a String special here as opposed to a
Fixnum or any other object?

An example would be a path name. The real code actually goes a bit
further to validate each element of the array too.

···

On Jun 24, 3:57 pm, Jeremy Heiler <jeremyhei...@gmail.com> wrote:

Ah, Sweet! Forgot about that.

Thanks.

···

On Jun 24, 4:20 pm, Ryan Davis <ryand-r...@zenspider.com> wrote:

def foo= foo
@foo = Array(foo)
end

Very simple, I am writing the code to read in and validate and very
strict YAML specification. And the reason that the YAML spec if so
strict is to make it extremely easy to work with in the raw, i.e. an
end-user can read in the file with YAML.load_file and know exactly
what to expect without needing a special API or doing hardly anything
in the way of parsing the data provided.

···

On Jun 26, 9:16 pm, Leslie Viljoen <leslievilj...@gmail.com> wrote:

On Sat, Jun 25, 2011 at 7:38 AM, Intransition <transf...@gmail.com> wrote:
> Well, for about the first time I am writing a library that has to be
> very strict about types. Per the usual I am testing types with `case`,

I am interested to know why it has to be strict about types?

> def foo= foo
> @foo = Array(foo)
> end

Ah, Sweet! Forgot about that.

Be careful with strings. Array() may not do what you want depending on
your target ruby:

  irb(main):001:0> RUBY_VERSION
  => "1.9.2"
  irb(main):002:0> Array("hello\nworld").length
  => 1
  irb(main):003:0>

  >> RUBY_VERSION
  => "1.8.7"
  >> Array("hello\nworld").length
  => 2
  >>

Depending on your inputs, you may need to check for a String.

···

On Sat, Jun 25, 2011 at 05:47:14AM +0900, Intransition wrote:

On Jun 24, 4:20 pm, Ryan Davis <ryand-r...@zenspider.com> wrote:

--
Aaron Patterson
http://tenderlovemaking.com/

That sounds reasonable, but I still think it depends on what you're
really trying to do.

Iv'e always considered #to_ary to mean: "transform my state into an
array, which may or may not be expensive." In which I would leave it
up to the programmer to decide if they want to call #to_a, and let it
fail if they don't.

My opinion here would be different if it meant: "here's my state as an
array, which I have been keeping up-to-date all along.

···

On Fri, Jun 24, 2011 at 4:09 PM, Intransition <transfire@gmail.com> wrote:

On Jun 24, 3:57 pm, Jeremy Heiler <jeremyhei...@gmail.com> wrote:

It depends. Do you want to? I suppose the only disadvantage would be
the cost of an object possibly creating a new array when to_ary is
invoked.

No, I don't really :wink: But... I've always been under the impression
that something that responds to #to_ary should be treated as such.
Thanks to duck-typing I've never really had to give it much thought
before.

F**k!

And my code just looked so pretty there for a while :-/

···

On Jun 24, 5:56 pm, Aaron Patterson <aa...@tenderlovemaking.com> wrote:

Be careful with strings. Array() may not do what you want depending on
your target ruby:

irb(main):001:0> RUBY_VERSION
=> "1.9.2"
irb(main):002:0> Array("hello\nworld").length
=> 1
irb(main):003:0>

>> RUBY_VERSION
=> "1.8.7"
>> Array("hello\nworld").length
=> 2
>>

Depending on your inputs, you may need to check for a String.