[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Idiomatic Ruby for Array#extract / Range#length?

Olivier

9/22/2007 6:06:00 PM

Le jeudi 20 septembre 2007 14:28, Sammy Larbi a écrit :
> During the monthly meeting of our code dojo, we were surprised by a couple
> of things in Ruby, so I had a couple of questions I'd like to ask the
> community:
>
> 1) Would it make sense to talk about a Range having a length, as in:
>
> class Range
> def length
> self.end - self.begin
> end
> end

This code will work only when begin and end respond to #-. This is a valid
implementation for Numeric objects, but not for other classes.
In the general case, you'd have to generate every objects of the range to
count them (using #to_a and #size).
And as the previous posts were debating, some ranges are not able to generate
the objects in the Range : the ranges of objects that do not respond to
#succ. And some ranges can be infinite.
By the way, generating all objects and counting is not restricted to Range,
but is general for any other Enumerable.

>
> 2) What about a 2 dimensional slice (you want a submatrix, for example)?
>
> def test_extract_submatrix
> assert_equal [[1,2,3],[4,5,6],[7,8,9]].extract_submatrix(1..2,1..2)
> , [[5,6],[8,9]]
> end
>
> class Array
> def extract_submatrix(row_range, col_range)
> self[row_range].transpose[col_range].transpose
> end
> end

Yes, this may be a useful method. It could be extended for use with
n-dimensional arrays.
Take a look to NArray library. I'm not sure, but I think it can do what you
are looking for, in an optimized way.

> 3) Are the better/more idiomatic ways to do these?

Your code is fine :)

> 4) Excuse my ignorance, as I've yet to use Facets, but are these the type
> of things it adds (and more)? Are they already in there?

Yes, the submatrix thing is the kind of method I could expect to see in
Facets. I'm not aware of the existence of such a method, though.

> Thanks and kind regards,
> Sam

--
Olivier Renaud


1 Answer

Rick DeNatale

9/22/2007 7:25:00 PM

0

On 9/22/07, Olivier Renaud <o.renaud@laposte.net> wrote:
> Le jeudi 20 septembre 2007 14:28, Sammy Larbi a écrit:
> > During the monthly meeting of our code dojo, we were surprised by a couple
> > of things in Ruby, so I had a couple of questions I'd like to ask the
> > community:
> >
> > 1) Would it make sense to talk about a Range having a length, as in:
> >
> > class Range
> > def length
> > self.end - self.begin
> > end
> > end
>
> This code will work only when begin and end respond to #-. This is a valid
> implementation for Numeric objects, but not for other classes.
> In the general case, you'd have to generate every objects of the range to
> count them (using #to_a and #size).

I think that it's debatable even in the case of Numerics, for example:

(1.2..1.5).length #=> 0.3

Normally length returns the number of elements in a collection, and
the method as provided doesn't actually work correctly for integer
ranges, it should be:

class Range
def length
1 + last - first
end
end

But, what about:

(1...3).length

end-start would give 2 but:

(1...3).to_a => [1, 2]

To fix this:

class Range
def length
last - first + (exclude_end? ? 0 : 1)
end
end

Now we have another case:

(3..1).to_a #=> []

so:

class Range
def length
[0, last - first + (exclude_end? ? 0 : 1)].max
end
end

But then what about:

(1.2..1.5).length

A collection can't have 0.3 elements!

I think it only makes sense for Integer ranges.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...