efficient comparators (namespaces for $a and $b) 
Author Message
 efficient comparators (namespaces for $a and $b)

What is (an | the most) efficient, namespace independant, method of
setting $a and $b for a user-provided comparator (a la sort's
comparator)?

I have a comparator sub passed to a processor routine e.g.:


and in process:

{

  ...
  # cmp1/2 are the things I need to "pass" to the comparator
  $a = $cmp1;
  $b = $cmp2;
  &$cmp;
  ...

Quote:
}

The thing is, process() could be called from any namespace. i.e. the
above fails (assuming process is not in blah::):

package blah;

The only ways I can see out of it:
1. force $main::a, $main::b and document as such
   pro: fastest?
   con: toasts main::a/b

2. wrap process' call to cmp in an eval to set the caller's namespace
before calling &$cmp
   pro: everything in its place
   con: presumably much slower

Any comments/suggestions?

Regards,

Ben Low

_____________________________________________________________________________
http://www.*-*-*.com/ - Yahoo! Movies
- Now showing: Dude Where's My Car, The Wedding Planner, Traffic..



Wed, 01 Oct 2003 21:08:17 GMT  
 efficient comparators (namespaces for $a and $b)

Quote:

> What is (an | the most) efficient, namespace independant, method of
> setting $a and $b for a user-provided comparator (a la sort's
> comparator)?

> I have a comparator sub passed to a processor routine e.g.:


> and in process:

> {

>   ...
>   # cmp1/2 are the things I need to "pass" to the comparator
>   $a = $cmp1;
>   $b = $cmp2;
>   &$cmp;
>   ...
> }

> The thing is, process() could be called from any namespace. i.e. the
> above fails (assuming process is not in blah::):


{

  # ...

  my $caller = caller;
  no strict 'refs';
  local *a = \${"${caller}::a"};
  local *b = \${"${caller}::b"};

  # cmp1/2 are the things I need to "pass" to the comparator
  $a = $cmp1;
  $b = $cmp2;
  &$cmp;
  # ...

Quote:
}

or if you prefer no minimise the use of package variables...


{

  # ...
  my ($a,$b);
  {
    my $caller = caller;
    no strict 'refs';
    $a = \${"${caller}::a"};
    $b = \${"${caller}::b"};
  }

  # cmp1/2 are the things I need to "pass" to the comparator
  $$a = $cmp1;
  $$b = $cmp2;
  &$cmp;
  # ...

Quote:
}

--
     \\   ( )
  .  _\\__[oo

 .  l___\\
  # ll  l\\
 ###LL  LL\\


Fri, 03 Oct 2003 01:59:09 GMT  
 efficient comparators (namespaces for $a and $b)

Quote:

> What is (an | the most) efficient, namespace independant, method of
> setting $a and $b for a user-provided comparator (a la sort's
> comparator)?

> I have a comparator sub passed to a processor routine e.g.:


[snip]
> The thing is, process() could be called from any namespace. i.e. the
> above fails (assuming process is not in blah::):

> package blah;

> The only ways I can see out of it:
> 1. force $main::a, $main::b and document as such
>    pro: fastest?
>    con: toasts main::a/b

> 2. wrap process' call to cmp in an eval to set the caller's namespace
> before calling &$cmp
>    pro: everything in its place
>    con: presumably much slower

3. Briefly clobber the caller's $a and $b with our own.


        no strict refs;
        my $cmp = shift;
        my $caller = caller;
        local *{"${caller}::a"} = \$a;
        local *{"${caller}::b"} = \$b;
        # The local assignments mean that the $a and $b of the caller's
        # package (presumably where $cmp came from) are the same $a and
        # $b as we see in this package.
        &$cmp;

        # without copying.

Quote:
}

4. Briefly clobber our own $a and $b with the caller's.


        no strict refs;
        my $cmp = shift;
        my $caller = caller;
        local *a = \${"${caller}::a"};
        local *b = \${"${caller}::b"};
        # The local assignments mean that the $a and $b which we see
        # in our package are in reality the $a and $b of the caller's
        # package.
        &$cmp;

Quote:
}

Note that 2, 3, and 4 all depend on $cmp having been created in the
caller's package.  If $cmp were created in package X, then stored in a
global, and then used in package Y, in a call to process, which in turn
is in package Z, they wouldn't work.

5. This could be avoided by having $cmp blessed (with the one argument
version of bless) at the time of creation, and using ref() instead of
caller().  Actually, that is a cleaner solution all around, but has the
annoying requirement of blessing the sub.  Perhaps a hybrid solution?


        no strict refs;
        my $cmp = shift;
        my $caller = ref($cmp) || caller;
        local *a = \${"${caller}::a"};
        local *b = \${"${caller}::b"};
        # The local assignments mean that the $a and $b which we see
        # in our package are in reality the $a and $b of the caller's
        # package.
        &$cmp;

Quote:
}

package X;

# ok, ref returns undef, caller() returns X, which "happens" to be the
# place where $cmp was defined.
$cmp = bless sub { $a <=> $b };
Y::sub_which_uses_process( $cmp );
# Since ref($cmp) returns X, it doesn't matter that caller would return
# Y from within process(), since ref is on the left of the ||

--

7835 1ddf07 23a871 72656b63); print map {$e=1;for(split//){$e*=$_};pack
'V',$e} qw(ptk ppppprre pperrrlau ppppphc ppjsa r);



Sat, 15 Nov 2003 17:13:49 GMT  
 efficient comparators (namespaces for $a and $b)

Quote:

> If $cmp were created in package X, then stored in a
> global, and then used in package Y, in a call to process, which in turn
> is in package Z, they wouldn't work.

$ perl -MDevel::Peek -e 'my $x; { package FOO; sub BAR::x {} }; Dump \&BAR::x'
SV = RV(0x810a0a8) at 0x80f39a0
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x811fe48
  SV = PVCV(0x81356f0) at 0x811fe48
    REFCNT = 2
    FLAGS = ()
    IV = 0
    NV = 0
    COMP_STASH = 0x810276c      "FOO"
    START = 0x8102b80 ===> 1492
    ROOT = 0x8100fe8
    XSUB = 0x0
    XSUBANY = 0
    GVGV::GV = 0x8135208        "BAR" :: "x"
    FILE = "-e"
    DEPTH = 0
    FLAGS = 0x0
    PADLIST = 0x8102754
    OUTSIDE = 0x80f3b08 (MAIN)


Sat, 15 Nov 2003 21:48:23 GMT  
 efficient comparators (namespaces for $a and $b)

Quote:

> > If $cmp were created in package X, then stored in a
> > global, and then used in package Y, in a call to process, which in turn
> > is in package Z, they wouldn't work.

> $ perl -MDevel::Peek -e 'my $x; { package FOO; sub BAR::x {} }; Dump \&BAR::x'
> SV = RV(0x810a0a8) at 0x80f39a0
>   REFCNT = 1
>   FLAGS = (TEMP,ROK)
>   RV = 0x811fe48
>   SV = PVCV(0x81356f0) at 0x811fe48
>     REFCNT = 2
>     FLAGS = ()
>     IV = 0
>     NV = 0
>     COMP_STASH = 0x810276c "FOO"
>     START = 0x8102b80 ===> 1492
>     ROOT = 0x8100fe8
>     XSUB = 0x0
>     XSUBANY = 0
>     GVGV::GV = 0x8135208   "BAR" :: "x"
>     FILE = "-e"
>     DEPTH = 0
>     FLAGS = 0x0
>     PADLIST = 0x8102754
>     OUTSIDE = 0x80f3b08 (MAIN)

Oops - missed the end of my post.

The point I was about to make is that it must be trivial to write an
XS function that takes a CODE reference and returns the COMP_STASH
name.

I'm not aware of any current module that contains such a function and
I can't even think where it would best be put.

--
     \\   ( )
  .  _\\__[oo

 .  l___\\
  # ll  l\\
 ###LL  LL\\



Mon, 17 Nov 2003 01:49:02 GMT  
 efficient comparators (namespaces for $a and $b)

Quote:

> The point I was about to make is that it must be trivial to write an
> XS function that takes a CODE reference and returns the COMP_STASH
> name.

B::svref_2obj(\&sub)->STASH->NAME;

--
diff: usage diff [whatever] etc.
    - plan9 has a bad day



Mon, 17 Nov 2003 17:55:16 GMT  
 efficient comparators (namespaces for $a and $b)
[A complimentary Cc of this posting was sent to
Simon Cozens

Quote:
> B::svref_2obj(\&sub)->STASH->NAME;

For those wanting to test it, here is a working example (thus without
misprints ;-).

 perl -MB -wle "{package A; sub C::D {}} print B::svref_2object(\&C::D)->STASH->NAME"

Hope this helps,
Ilya



Tue, 18 Nov 2003 05:43:32 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. dbase file problems!

2. I don't wont work with Application from Microsoft !

3. `du -bs $dir` question

4. XSUB, .bs, PDF, FDF

5. Size of Tk.bs file in auto directory

6. Q: efficient string copy without using refs

7. efficient string copy without using refs

8. Efficient frontend with jobcontrol wanted

9. Pointer Artithmetic on DB_File values: i need it (or a very efficient solution for this problem)

10. Is this the most efficient method

11. algorithm help - efficient cd use

12. Efficient reading of fixed-length records

 

 
Powered by phpBB® Forum Software