capturing access to array elements

Discussion in 'Ruby' started by mortee, Sep 18, 2007.

  1. mortee

    mortee Guest

    Hi,

    my question may sound a bit amateur, but I'm just starting to play
    around with Ruby.

    So which methods in Array do I have to override, if I want to make sure
    I can capture any attempt to access an array element? In other words,
    which are the Array methods which don't rely on other ones to access
    elements?

    I haven't found this mentioned in any documentation I came across.

    thx
    mortee
     
    mortee, Sep 18, 2007
    #1
    1. Advertising

  2. mortee

    Phrogz Guest

    On Sep 18, 11:10 am, mortee <> wrote:
    > So which methods in Array do I have to override, if I want to make sure
    > I can capture any attempt to access an array element? In other words,
    > which are the Array methods which don't rely on other ones to access
    > elements?


    Unfortunately, there isn't a single method that accesses the value at
    a particular index. For example, see the following code. Note that the
    #[] method isn't called by the other methods, including each. (Note
    also that the following is not an exhaustive list, but does give you a
    starting point for experimentally determining which method might call
    others.)

    a = %w| a b c |

    def a.[]( *args, &blk )
    p '[]'
    super *args, &blk
    end

    def a.each( *args, &blk )
    p 'each'
    super *args, &blk
    end

    def a.select( *args, &blk )
    p 'select'
    super *args, &blk
    end

    def a.delete( *args, &blk )
    p 'delete'
    super *args, &blk
    end

    def a.fetch( *args, &blk )
    p 'fetch'
    super *args, &blk
    end

    puts "Using []:"
    a[ 0 ]

    puts "-"*40

    puts "Using each:"
    a.each{ |x| }

    puts "-"*40

    puts "Using select:"
    a.select{ |x| }

    puts "-"*40

    puts "Using delete:"
    a.delete 'b'

    puts "-"*40

    puts "Using fetch:"
    a.fetch 1
     
    Phrogz, Sep 18, 2007
    #2
    1. Advertising

  3. On 18.09.2007 20:47, Phrogz wrote:
    > On Sep 18, 11:10 am, mortee <> wrote:
    >> So which methods in Array do I have to override, if I want to make sure
    >> I can capture any attempt to access an array element? In other words,
    >> which are the Array methods which don't rely on other ones to access
    >> elements?

    >
    > Unfortunately, there isn't a single method that accesses the value at
    > a particular index. For example, see the following code. Note that the
    > #[] method isn't called by the other methods, including each. (Note
    > also that the following is not an exhaustive list, but does give you a
    > starting point for experimentally determining which method might call
    > others.)


    Having said that it's probably easier to use Delegator to intercept
    method calls. Maybe there's also another approach to solving this.
    Mortee, what are you trying to achieve?

    Kind regards

    robert
     
    Robert Klemme, Sep 18, 2007
    #3
  4. mortee wrote:
    > So which methods in Array do I have to override, if I want to make sure
    > I can capture any attempt to access an array element?


    My chattr gem does this so it can do type-checking. It's small, install it and have a read.

    Clifford Heath.
     
    Clifford Heath, Sep 19, 2007
    #4
  5. mortee

    mortee Guest

    >> Unfortunately, there isn't a single method that accesses the value at
    >> a particular index. For example, see the following code. Note that the
    >> #[] method isn't called by the other methods, including each. (Note
    >> also that the following is not an exhaustive list, but does give you a
    >> starting point for experimentally determining which method might call
    >> others.)

    >
    > Having said that it's probably easier to use Delegator to intercept
    > method calls. Maybe there's also another approach to solving this.
    > Mortee, what are you trying to achieve?


    Actually it's indifferent if I use Delegator or not. In my scenario, I
    get an array of record from a library function, and I want to have those
    records automatically extended with a module's methods, without any
    extra work on the array's user's part (aside from once handling the
    array itself).

    But I don't want to traverse the array right when I do this action in
    question on the array: I'd like to leave it that to the time the
    elements are actually accessed. This is because I want to have records
    added to the array afterwards be extended also; and it may take
    time-consuming actions for the "array" to fetch its elements, so I don't
    want to access them if not necessary.

    That's why I opted to override its element-accessor methods. I guess the
    main principle would be the same whether I override the methods of the
    array object in question itself, or I use a delegator object which wraps
    the array's methods (currently I use the latter, but I'd prefer the
    former anyway).

    mortee
     
    mortee, Sep 19, 2007
    #5
  6. 2007/9/19, mortee <>:
    > >> Unfortunately, there isn't a single method that accesses the value at
    > >> a particular index. For example, see the following code. Note that the
    > >> #[] method isn't called by the other methods, including each. (Note
    > >> also that the following is not an exhaustive list, but does give you a
    > >> starting point for experimentally determining which method might call
    > >> others.)

    > >
    > > Having said that it's probably easier to use Delegator to intercept
    > > method calls. Maybe there's also another approach to solving this.
    > > Mortee, what are you trying to achieve?

    >
    > Actually it's indifferent if I use Delegator or not. In my scenario, I
    > get an array of record from a library function, and I want to have those
    > records automatically extended with a module's methods, without any
    > extra work on the array's user's part (aside from once handling the
    > array itself).
    >
    > But I don't want to traverse the array right when I do this action in
    > question on the array: I'd like to leave it that to the time the
    > elements are actually accessed. This is because I want to have records
    > added to the array afterwards be extended also; and it may take
    > time-consuming actions for the "array" to fetch its elements, so I don't
    > want to access them if not necessary.
    >
    > That's why I opted to override its element-accessor methods. I guess the
    > main principle would be the same whether I override the methods of the
    > array object in question itself, or I use a delegator object which wraps
    > the array's methods (currently I use the latter, but I'd prefer the
    > former anyway).


    Actually I believe the delegation approach (whether with Delegator or
    other) is the superior approach. Although not with problems of its own
    (object identity) wrapping something in order to control access to it
    seems the most natural way to do it because there is no way left for
    direct manipulation of the Array (yes, I know that you can work your
    way around that). My 0.02 EUR.

    Kind regards

    robert
     
    Robert Klemme, Sep 19, 2007
    #6
  7. mortee

    mortee Guest

    > My chattr gem does this so it can do type-checking. It's small, install
    > it and have a read.


    It looks great, but it doesn't seem to be applicable in my case. I have
    to deal with arrays already created by a library function and returned
    to me, so I can't prescribe their actual class.

    mortee
     
    mortee, Sep 19, 2007
    #7
  8. mortee

    mortee Guest

    Robert Klemme wrote:
    > Actually I believe the delegation approach (whether with Delegator or
    > other) is the superior approach. Although not with problems of its own
    > (object identity) wrapping something in order to control access to it
    > seems the most natural way to do it because there is no way left for
    > direct manipulation of the Array (yes, I know that you can work your
    > way around that). My 0.02 EUR.


    You're right in a sense, and not in another. Currently, I use delegation
    for the exact same reason you mention: I can control all access to the
    underlying object.

    But I'd also want to have my object as a fully capable Array, so I'd
    have to cover all the Array methods anyway. And if that's the case, I
    may just override the object's methods themselves just as well.

    Delegation seemed slower to me than extending the object itself. But I
    may be confused by some other factors - I haven't done precise
    measurements discarding any other influences.

    mortee
     
    mortee, Sep 19, 2007
    #8
  9. mortee wrote:
    >> My chattr gem does this so it can do type-checking. It's small, install
    >> it and have a read.

    > It looks great, but it doesn't seem to be applicable in my case. I have
    > to deal with arrays already created by a library function and returned
    > to me, so I can't prescribe their actual class.


    No, but you can re-open the class that they are of, and apply all
    the methods from chattr, which replicates exactly the behaviour of
    the standard Array class, so you know you haven't broken anything
    by interjecting.
     
    Clifford Heath, Sep 19, 2007
    #9
  10. mortee

    mortee Guest

    Clifford Heath wrote:
    > No, but you can re-open the class that they are of, and apply all
    > the methods from chattr, which replicates exactly the behaviour of
    > the standard Array class, so you know you haven't broken anything
    > by interjecting.


    Sounds possible. I'll give it a try, thanks.

    mortee
     
    mortee, Sep 21, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Adam Warner
    Replies:
    13
    Views:
    928
    Patricia Shanahan
    Mar 28, 2006
  2. P
    Replies:
    1
    Views:
    1,201
    Joe Kesselman
    Jul 7, 2006
  3. Replies:
    4
    Views:
    531
  4. Venks
    Replies:
    10
    Views:
    238
    MonkeeSage
    Dec 7, 2007
  5. Arti Singh
    Replies:
    2
    Views:
    145
    Arti Singh
    Jul 26, 2010
Loading...

Share This Page