problems passing ref to "join" builtin 
Author Message
 problems passing ref to "join" builtin

I was trying to pass the function "join" as an argument to another
function but perl complained that main::join didn't exist.


So I figured that the perl builtins must live in another name space.
After some further poking around, I received a message regarding
"CORE::join" so I figured that the builtins must live in the "CORE"
package.  With this, I tried the educated guess:


but with no success.  Perl complained that CORE::join did not exist
either.

Therefore, my question is, is it possible to pass references to builtin
functions, and if so, how?

-ted

--



Sun, 14 Dec 2003 11:22:37 GMT  
 problems passing ref to "join" builtin

Quote:
>I was trying to pass the function "join" as an argument to another
>function but perl complained that main::join didn't exist.


>So I figured that the perl builtins must live in another name space.
>After some further poking around, I received a message regarding
>"CORE::join" so I figured that the builtins must live in the "CORE"
>package.  With this, I tried the educated guess:



join isn't a subroutine, so '&join' and '&CORE::join' just lead to trouble.

Why do you want to pass a core function as an argument?

Perhaps you could pass a flag, so the subroutine knows that you want
the join function to be applied.

# untested
sub fancy_function {

   # ...
   if ($func_flag eq 'j') {
     return join $arg1 => $arg2, $arg3
   } elsif ($func_flag eq 's') {
     return split /$arg1/ => $arg2
   } elsif ($func_flag eq 'r') {
     return rejoin $arg3 => $arg2 => $arg1
   }
   # ...

Quote:
}

Or how about making up your own subroutine, for which you *may* pass a coderef:

# untested
sub join_these {


Quote:
}

HTH

1;
--

   - Bruce

__bruce_van_allen__santa_cruz_ca__



Sun, 14 Dec 2003 21:44:06 GMT  
 problems passing ref to "join" builtin

You could use an anonymous code reference which DTRT, like so:


I don't think you can make a hard (or symbolic?) reference to
builtin functions at all, but I can't find it written down in my
camel, and a quick grep through perlref doesn't help me either, so
it's possible (perhaps even quite likely) that I'm mistaken.

--
Mike Bristow, seebitwopie  



Sun, 14 Dec 2003 21:58:20 GMT  
 problems passing ref to "join" builtin

Quote:
>join isn't a subroutine, so '&join' and '&CORE::join' just lead to
>trouble.

I suppose there must be some difference between a 'subroutine' and a
'function' listed in perlfunc(1).  It would certainly be nicer if you
could treat them the same way.  But this kind of special-case stuff is
what makes Perl so charming.

You might think you could get around the problem with


or for efficiency

$sub_ref = sub { &join };

but neither of these seems to work with 5.005_03.


[no output except a newline]
% perl -e '$r = sub { &join }; print $r->(",", "a", "b"), "\n"'
Undefined subroutine &main::join called at -e line 1.

The first one is worrying; shouldn't join just take a flat list of
scalars?  I suppose this is another consequence of join being a
'function' and not a subroutine.

However an even more awkward way works:


a,b

So I'd suggest using


unless you have a newer perl which has cleaned up some of this mess.

--

Finger for PGP key



Sun, 14 Dec 2003 22:40:16 GMT  
 problems passing ref to "join" builtin


Quote:
> With this, I tried the educated guess:


>but with no success.  Perl complained that CORE::join did not exist
>either.

>Therefore, my question is, is it possible to pass references to builtin
>functions, and if so, how?

No.  perlsub sez:

  To unambiguously refer to the built-in form, precede the built-in name
  with the special package qualifier CORE::. For example, saying
  CORE::open() always refers to the built-in open(), even if the current
  package has imported some other subroutine called &open() from
  elsewhere. Even though it looks like a regular function call, it isn't: you
  can't take a reference to it, such as the incorrect \&CORE::open might
  appear to produce.

--
Peter Scott
http://www.perldebugged.com



Mon, 15 Dec 2003 00:44:57 GMT  
 problems passing ref to "join" builtin
The following works with 5.005_03.


a,b

The syntax for join is: 'join EXPR, LIST' (or in prototype form



the same as 'join(3)', which returns a string of zero items separated
by the character '3', which is just a null string.  To illustrate:


c3d

I hope that clears up how and why it works the way it does.

I do not have an answer as to why '&join' and '&CORE::join'
do not work.  Join may be hidden in some other package -- or it
may just be magic. :-)

Quote:


> >join isn't a subroutine, so '&join' and '&CORE::join' just lead to
> >trouble.

> I suppose there must be some difference between a 'subroutine' and a
> 'function' listed in perlfunc(1).  It would certainly be nicer if you
> could treat them the same way.  But this kind of special-case stuff is
> what makes Perl so charming.

> You might think you could get around the problem with


> or for efficiency

> $sub_ref = sub { &join };

> but neither of these seems to work with 5.005_03.


> [no output except a newline]
> % perl -e '$r = sub { &join }; print $r->(",", "a", "b"), "\n"'
> Undefined subroutine &main::join called at -e line 1.

> The first one is worrying; shouldn't join just take a flat list of
> scalars?  I suppose this is another consequence of join being a
> 'function' and not a subroutine.

> However an even more awkward way works:


> a,b

> So I'd suggest using


> unless you have a newer perl which has cleaned up some of this mess.

> --

> Finger for PGP key

--


Department of Chemistry and Biochemistry
University of Oklahoma
620 Parrington Oval, Room 313
Norman, OK 73019-3051
Phone: (405) 325-4912, FAX: (405) 325-7762



Mon, 15 Dec 2003 00:30:06 GMT  
 problems passing ref to "join" builtin

Quote:

>>join isn't a subroutine, so '&join' and '&CORE::join' just lead to
>>trouble.

>I suppose there must be some difference between a 'subroutine' and a
>'function' listed in perlfunc(1).  It would certainly be nicer if you
>could treat them the same way.  But this kind of special-case stuff is
>what makes Perl so charming.

>You might think you could get around the problem with


>or for efficiency

>$sub_ref = sub { &join };

>but neither of these seems to work with 5.005_03.

"Treating them the same way" would require accounting for input
constraints, among other things.



So I wouldn't expect

to work, either.

It doesn't work because 'join' requires as input a scalar and then a
list. If it were a subroutine, it would be prototyped:


   my $f = shift;

Quote:
}


print $a; # nothing


print $a; # ,*a*b

That's why your solution is the best:


although it could be compressed without too much obfuscation:


Why is 'join' in effect prototyped? We can do this:
  print join '*', 'a', 'b', 'c';  # a*b*c

So why can't we do this?

It's easier to understand why 'push' is effectively prototyped

because the list is named first, and without input constraints the
item being pushed onto the list would not stay distinct in the arg
list.

I haven't been able to think of an example in which I wouldn't want

to work. Anyone else??

1;

--

   - Bruce

__bruce_van_allen__santa_cruz_ca__



Mon, 15 Dec 2003 00:49:41 GMT  
 problems passing ref to "join" builtin

Quote:
>The following works with 5.005_03.


>a,b

>The syntax for join is: 'join EXPR, LIST' (or in prototype form



But perlsub(1) says:

Quote:
>all functions are passed as parameters one single flat list of
>scalars,

So there shouldn't be a difference between

join('foo', 'bar', 'baz')
join(('foo', 'bar'), baz')
join(qw/foo bar baz/)

or any other variant.  If there is, then perlsub (and the advice often
given to Perl newbies) is wrong.

Quote:

>the same as 'join(3)', which returns a string of zero items separated
>by the character '3', which is just a null string.


behaviour.

Quote:
>I hope that clears up how and why it works the way it does.

How, yes; why, not really.

--

Finger for PGP key



Mon, 15 Dec 2003 02:53:13 GMT  
 problems passing ref to "join" builtin

Quote:


>Why is 'join' in effect prototyped? We can do this:
>  print join '*', 'a', 'b', 'c';  # a*b*c

>So why can't we do this?

>It's easier to understand why 'push' is effectively prototyped




the end.)

In the case of push, the prototype is needed to get the modifying
behaviour, but it's not clear why join needs a prototype.  After all
many Perl examples (in O'Reilly books and the like) have subroutines
that take a flat list, pop off the first element and do something with
that and the rest of the list.  It seems to work well enough.

Quote:
>I haven't been able to think of an example in which I wouldn't want

>to work.

Do you mean '...in which I *would* want it to work'?  The only case I
can think of is some kind of wrapper around join() which calls join()
with its own argument list.

--

Finger for PGP key



Mon, 15 Dec 2003 02:59:07 GMT  
 problems passing ref to "join" builtin

Quote:
>I haven't been able to think of an example in which I wouldn't want

>to work. Anyone else??

But I'm *not* proposing that 'join' be changed.

Just searching for a rationale-by-example for its 'prototyped' behavior.
--

   - Bruce

__bruce_van_allen__santa_cruz_ca__



Mon, 15 Dec 2003 01:39:47 GMT  
 problems passing ref to "join" builtin

Quote:


>>I haven't been able to think of an example in which I wouldn't want

>>to work. Anyone else??

> But I'm *not* proposing that 'join' be changed.

> Just searching for a rationale-by-example for its 'prototyped'
> behavior.

Well, it isn't quite compelling yet, but perhaps someone else can
flesh it out:

#!/usr/bin/perl
use strict;
use warnings;

sub flat_join {

Quote:
}



Quote:
}

sub sep { wantarray ? ":" : "-" }

print flat_join(sep(), qw/a b c/), "\n";
print proto_join(sep(), qw/a b c/), "\n";
print join(sep(), qw/a b c/), "\n";
__END__                                
a:b:c
a-b-c
a-b-c

The point is that without the prototype for a scalar first argument,
then that first argument will be in a list context.  I assume there
must be some useful example that demonstrates this behavior other than
my contrived sep().

--
Ren Maddox



Mon, 15 Dec 2003 04:02:10 GMT  
 problems passing ref to "join" builtin

Quote:

>>So why can't we do this?



   nullnullnull

Quote:
>>It's easier to understand why 'push' is effectively prototyped



>the end.)


Quote:
>In the case of push, the prototype is needed to get the modifying
>behaviour, but it's not clear why join needs a prototype.  After all
>many Perl examples (in O'Reilly books and the like) have subroutines
>that take a flat list, pop off the first element and do something with
>that and the rest of the list.  It seems to work well enough.

>>I haven't been able to think of an example in which I wouldn't want

>>to work.

>Do you mean '...in which I *would* want it to work'?  The only case I
>can think of is some kind of wrapper around join() which calls join()
>with its own argument list.

Which was sort of how this topic came in. What I meant was that, in
trying understand the rationale for why 'join' is effectively

having the join EXPR as the first element of a single array arg
*shouldn't* work. If it would work with EXPR as the first element of
a flat list, then why not as the first element of an array?

Again, just a question; not a complaint or demand for a change in join...

1;
--

   - Bruce

__bruce_van_allen__santa_cruz_ca__



Mon, 15 Dec 2003 04:32:09 GMT  
 problems passing ref to "join" builtin

Quote:
> >Therefore, my question is, is it possible to pass references to builtin
> >functions, and if so, how?

> No.  perlsub sez:

>   To unambiguously refer to the built-in form, precede the built-in name
>   with the special package qualifier CORE::. For example, saying
>   CORE::open() always refers to the built-in open(), even if the current
>   package has imported some other subroutine called &open() from
>   elsewhere. Even though it looks like a regular function call, it isn't: you
>   can't take a reference to it, such as the incorrect \&CORE::open might
>   appear to produce.

Jumping back in to my own post, I find that horribly disappointing!
There is no reason why a builtin shouldn't behave like a defined
subroutine in most all respects.  We do this in Lisp all the time:

  (apply #'+ (1 2 3 4 5)) => 15

-ted

Quote:

> --
> Peter Scott
> http://www.perldebugged.com

--



Mon, 15 Dec 2003 12:09:01 GMT  
 
 [ 13 post ] 

 Relevant Pages 

1. TP7: Graphical mode apps under win xp

2. "character class ""bug""

3. problem passing 1st agrument with "eval 'exec perl -w -d -s $0 ${1+"$@"}'"

4. Validation mess - Totally wrong track?

5. How to create .MDX files?

6. TP 6.0 TurboVision problem.

7. Index Logical?

8. Passing an array of "pointers"

9. Passing two lists to a "sub"

10. passing "=" as an argument to CGI

11. passing ";" as an argument

12. Passing "#" to browser

 

 
Powered by phpBB® Forum Software