Array_Of(AClass)

i wonder, a coding challenge of sorts, what would it talk to create an
Array_Of(AClass) constructor? such that an array would be created that can
only contain objects of the class specified.

···


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.’’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:’.:::. | ’ ‘’ * ‘.’/.’ (/’.’:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
’…’ ‘:::’ === * /\ * .’/.’. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-’| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /"\ | '-."". ‘-’ ‘-.’ '` |.

Oh, so you want type checking now? :wink:

Pretty simple, I would think. Find all the methods that can add or change
elements in the array, and add type checks to it.

Tim Bates

···

On Mon, 13 Jan 2003 05:07 pm, Tom Sawyer wrote:

i wonder, a coding challenge of sorts, what would it talk to create an
Array_Of(AClass) constructor? such that an array would be created that can
only contain objects of the class specified.


tim@bates.id.au

Sorry, I give up. I can’t see how to do it elegantly. I guess it’s
just a poor fit for Ruby.

My approach was like this:

def ArrayOf(klass, *args)
the_array = Array.new(*args)
class << the_array

···

On Monday, January 13, 2003, 5:37:21 PM, Tom wrote:

i wonder, a coding challenge of sorts, what would it talk to create an
Array_Of(AClass) constructor? such that an array would be created that can
only contain objects of the class specified.

  #
  # Redefine ... here
  #
end
return the_array

end

Where “…” is

  • +(ary)

  • =(range, ary)

  • <<(obj)

  • =(idx, obj)

  • =(start, length, obj)

  • push(obj)

  • unshift(obj)

The methods are grouped like that because you need to typecheck the
last argument always. In the first two cases that argument will be an
array (and you need to check the type of all the elements). For the
rest you need to typecheck a single object.

= is a special case. The last argument can be an object OR an
array.

I think the approach of using a singleton class is good, because you
can access the underlying Array method with “super”. My first though
was delegation, or even a blank class with just #method_missing.
However, in these cases, the resulting object wouldn’t pass the “is_a?
Array” test.

I want to highlight this: from a singleton class, you can use “super”
like in normal inheritance. Keep this in mind if you are redefining
methods anytime. I find the pattern

alias_method :old_xxx, :xxx

def xxx

old_xxx

end

rather smelly. Much better is

class << obj
def xxx

super

end
end

I just learned that through this exercise, so I’m glad some good came
of it.

Gavin

I think, staying in line with OO principles, #all_responds_to?(x)
would be more appropriate. Then, you could say:

a = Array.new
a << "hi"
a << "there"

if a.all_responds_to? :upcase
    puts "Everything in array 'a' knows how to upcase itself."
end

Or, of course, something slightly more useful.

– Dossy

···

On 2003.01.13, Tim Bates tim@bates.id.au wrote:

On Mon, 13 Jan 2003 05:07 pm, Tom Sawyer wrote:

i wonder, a coding challenge of sorts, what would it talk to create an
Array_Of(AClass) constructor? such that an array would be created that can
only contain objects of the class specified.

Oh, so you want type checking now? :wink:

Pretty simple, I would think. Find all the methods that can add or change
elements in the array, and add type checks to it.


Dossy Shiobara mail: dossy@panoptic.com
Panoptic Computer Network web: http://www.panoptic.com/
“He realized the fastest way to change is to laugh at your own
folly – then you can let go and quickly move on.” (p. 70)

Sorry, I give up. I can’t see how to do it elegantly. I guess it’s
just a poor fit for Ruby.

yes, i have found it tricky too. you made a good start of it though. i’ll play
with it later and see what i can come up with.

I think the approach of using a singleton class is good, because you
can access the underlying Array method with “super”. My first though
was delegation, or even a blank class with just #method_missing.
However, in these cases, the resulting object wouldn’t pass the “is_a?
Array” test.

I want to highlight this: from a singleton class, you can use “super”
like in normal inheritance. Keep this in mind if you are redefining
methods anytime. I find the pattern

I just learned that through this exercise, so I’m glad some good came
of it.

ah now that is interesting! i’ll have to keep this in mind from hence forth.
thanks!

···

On Monday 13 January 2003 12:38 am, Gavin Sinclair wrote:


tom sawyer, aka transami
transami@transami.net

                               .''.
   .''.      .        *''*    :_\/_:     .
  :_\/_:   _\(/_  .:.*_\/_*   : /\ :  .'.:.'.

.‘’.: /\ : ./)\ ‘:’* /\ * : ‘…’. -=:o:=-
:/:‘.:::. | ’ ‘’ * ‘.'/.’ (/’.‘:’.’
: /\ : ::::: = / -= o =- /)\ ’ *
‘…’ ‘:::’ === * /\ * .‘/.'. ‘._____
* | : |. |’ .—"|
* | _ .–’| || | _| |
* | .-‘| __ | | | || |
.-----. | |’ | || | | | | | || |
__’ ’ /“\ | '-.”". ‘-’ ‘-.’ '` |.

Hi –

I want to highlight this: from a singleton class, you can use “super”
like in normal inheritance. Keep this in mind if you are redefining
methods anytime. I find the pattern

alias_method :old_xxx, :xxx

def xxx

old_xxx

end

rather smelly. Much better is

class << obj
def xxx

super

end
end

I just learned that through this exercise, so I’m glad some good came
of it.

Technique #2 is not a drop-in replacement for technique #1, though.
For example, if you want to “listen in” on what a method is doing,
you might do:

class String
alias :oldsplit :split
def split(*a)
puts “args are #{a.join(', ')}”
oldsplit(*a)
end
end

I don’t think there’s an equivalent way to do this by modifying the
object’s singleton class.

David

···

On Mon, 13 Jan 2003, Gavin Sinclair wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

If it’s just a single object, surely you can:

class << the_str
def split(*args)
puts “args are #{args.join(', ')}”
super
end
end

Which, again, is much nicer than aliasing. However, it only works on
one String instance, not all of them. Which was probably your point.

Gavin

···

On Tuesday, January 14, 2003, 9:59:44 AM, dblack wrote:

Technique #2 is not a drop-in replacement for technique #1, though.
For example, if you want to “listen in” on what a method is doing,
you might do:

class String
alias :oldsplit :split
def split(*a)
puts “args are #{a.join(', ')}”
oldsplit(*a)
end
end

I don’t think there’s an equivalent way to do this by modifying the
object’s singleton class.

I think eventually we’re going to get some kind
of mechanism like LISP’s defadvice (I seem to
recall a rumor like that).

Not that I know LISP or understand defadvice –
but it sounds a little like AOP to me. It came
up once when I suggested a “prior” keyword.

Hal

···

----- Original Message -----
From: “Gavin Sinclair” gsinclair@soyabean.com.au
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Monday, January 13, 2003 6:39 PM
Subject: Re: Array_Of(AClass)

On Tuesday, January 14, 2003, 9:59:44 AM, dblack wrote:

Technique #2 is not a drop-in replacement for technique #1, though.
For example, if you want to “listen in” on what a method is doing,
you might do:

class String
alias :oldsplit :split
def split(*a)
puts “args are #{a.join(', ')}”
oldsplit(*a)
end
end

I don’t think there’s an equivalent way to do this by modifying the
object’s singleton class.

If it’s just a single object, surely you can:

class << the_str
def split(*args)
puts “args are #{args.join(', ')}”
super
end
end

Which, again, is much nicer than aliasing. However, it only works on
one String instance, not all of them. Which was probably your point.