Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: My problems to understand the Perl documentation [updated]

by jo37 (Hermit)
on Aug 23, 2020 at 08:40 UTC ( #11121004=note: print w/replies, xml ) Need Help??


in reply to My problems to understand the Perl documentation

If you call split like this @rv = split $_[0], @_[ 1 .. 2 ] you get the return value undef.

This is not true, it gives (99). Update 1: Presuming @_ = (qr{:}, 'a:b:c', 99) from the given example. Update 2: A capturing group in the regex does not change the result for this case.

To understand this behaviour you need to consider function prototypes. The compiler recognises split being called with two arguments, where the second is a list that gets assigned to a single scalar. This results in the last element of the list being assigned to the scalar, just like in

$x = (1, 2, 4); # $x = 4
This behaviour is caused by the usage of an array slice. A "pure" array would be evaluated in scalar context giving its length.

In the following example the sub show_args sees its arguments just like split.

UPDATE 3: As suspected by bojinlund in Re^2: My problems to understand the Perl documentation and proven by LanX in Re^4: My problems to understand the Perl documentation, the sub show_args does not see its arguments exactly as split.

#!/usr/bin/perl use strict; use warnings; use Data::Dump 'dd'; use feature 'say'; sub show_args ($_;$) { dd @_; } sub call_show_args { say "single:"; show_args $_[0], $_[1], $_[2]; say "flat:"; show_args @_; say "slice:"; show_args @_[0 .. 2]; say "slice split:"; show_args $_[0], @_[1 .. 2]; say "array split:"; my $p = shift; show_args $p, @_; } $_ = 'default'; call_show_args qr{:}, 'a:b:c', 99; __DATA__ single: (qr/:/, "a:b:c", 99) flat: (3, "default") slice: (99, "default") slice split: (qr/:/, 99) array split: (qr/:/, 2)

Greetings,
-jo

$gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$

Replies are listed 'Best First'.
Re^2: My problems to understand the Perl documentation
by bojinlund (Prior) on Aug 23, 2020 at 18:59 UTC
    Thank you jo37 for your work!
    This is not true, it gives (99).

    Sorry, I had an error in my test script. Now I also get 99.

    Your example made me understand that a prototype also defines the context (scalar/list) for the evaluation of the arguments.

    My point is that the function split is not fully described in the Perl documentation

    • Reading index-functions I get the impression that split is a function.
    • In perlsub is stated:
    • The Perl model for function call and return values is simple: all functions are passed as parameters one single flat list of scalars, and all functions likewise return to their caller one single flat list of scalars. ...
    • The function prototype returns the prototype of a function as a string (or undef if the function has no prototype).
      prototype "CORE::split" returns undef (Thanks LanX )

    My conclusion from this is that split is a Perl sub, without prototype.

    I have however realized that:

    • Split's first argument, /PATTERN/, is not evaluated immediately. In some way it is kept for later usage.
    • The rest of the arguments are not treated like a Perl sub without prototype.

    Somewhere in split this differences from a normal Perl sub should be included. As split behaves more like an operator it is perhaps better to call it an operator. It is also implemented as an operator and not as a Perl sub.

      Reading index-functions I get the impression that split is a function.

      That list also includes things that are clearly not a function, like and, __END__, and m.

      The function prototype returns the prototype of a function as a string (or undef if the function has no prototype). prototype "CORE::split" returns undef

      You seem to be ignoring the part of that doc that says:

      If FUNCTION is a string starting with CORE::, the rest is taken as a name for a Perl builtin. If the builtin's arguments cannot be adequately expressed by a prototype (such as system), prototype returns undef, because the builtin does not really behave like a Perl function.
      As split behaves more like an operator it is perhaps better to call it an operator.

      Please read carefully Terms and List Operators (Leftward):

      Actually, there aren't really functions in this sense, just list operators and unary operators behaving as functions because you put parentheses around the arguments.

      Several things in Perl only make sense when you read all of the documentation.

      Split IS a builtin function.

      I told you already that the fact you can't easily replicate it with sub doesn't mean it's not a function.

      Perl is not Lisp where the whole syntax can be expressed with one single s-expression .

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      > Reading index-functions I get the impression that split is a function.

      That's taken from perlfunc and there it clearly states

      Here are Perl's functions (including things that look like functions, like some keywords and named operators ) arranged by category.

      It should better have been named "keyword-index"

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

      My conclusion from this is that split is a Perl sub, without prototype.

      Is there any built-in without a prototype? I don't think so.

      Greetings,
      -jo

      $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
        > Is there any built-in without a prototype? I don't think so.

        Yes, several.

        You can check yourself with prototype

        From the docs:

        If FUNCTION is a string starting with CORE:: , the rest is taken as a name for a Perl builtin.

        If the builtin's arguments cannot be adequately expressed by a prototype (such as system), prototype returns undef, because the builtin does not really behave like a Perl function.

        Otherwise, the string describing the equivalent prototype is returned.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        Is there any built-in without a prototype?

        On 5.28, prototype returns undef for at least the following (I may have missed a few, and I omitted most things that I think most people would classify as keywords and operators instead of functions, like use, goto, and -X):

        chomp chop defined delete do eval exec exists grep map print printf require return say select sort split system

        Added minor clarifications.

Re^2: My problems to understand the Perl documentation [updated]
by bojinlund (Prior) on Sep 02, 2020 at 07:35 UTC
    Sorry for taking so long time to create this post, but I needed some time to read and think. Monks thank you for your answers, they have been helpful.
    The goal you seem to have is to define Perl in Lisp'ish way, where everything can be derived from a small set of axioms.

    No, I just want to understand the documentation, and hopefully help others to do the same.

    This Re: My problems to understand the Perl documentation [updated] help me realize that I had missed Slices in scalar context return the last item of the slice. from perldata

    Split is an operator (op)

    From perlfunc, which is a list of Perl builtin functions. Split is in this list.

    The functions in this section can serve as terms in an expression. They fall into two major categories: list operators and named unary operators.

    From perlinterp : “An op is a fundamental operation that Perl can perform: all the built-in functions and operators are ops”

    From token.c in perl.git: case KEY_split: LOP(OP_SPLIT,XTERM);/

    From pp.c in perl.git:

    This file contains general pp ("push/pop") functions that execute the opcodes that make up a perl program. A typical pp function expects to find its arguments on the stack, and usually pushes its results onto the stack, hence the 'pp' terminology.
    PP(pp_split) { … } implements split.

    The de-parse of sub { split} does not show any subroutine call.

    Ideas to changes to the documentation

    Here follows a number of rough drafts to changes.

    Passing of arguments and return values

    This from perlsub is only one case:

    The Perl model for function call and return values is simple: all functions are passed as parameters one single flat list of scalars, and all functions likewise return to their caller one single flat list of scalars. Any arrays or hashes in these call and return lists will collapse, losing their identities--but you may always use pass-by-reference instead to avoid this. Both call and return lists may contain as many or as few scalar elements as you'd like. (Often a function without an explicit return statement is called a subroutine, but there's really no difference from Perl's perspective.)

    It only applies to Perl subs without Prototype or Signature. (I was mislead that it applied to any function.)

    Proposals to replace the quoted text above with:

    The arguments and return values are transferred using the argument stack.

    The subroutine arguments in the script source code is processed (evaluated), to store them on the argument stack. This is done before the call of the subroutine definition.

    Perl has two ways of processing the arguments before calling a function.

    • One single flat list of scalars
    • The arguments are passed as a single flat list of scalar values. Any arrays or hashes are collapsed and they are losing their identities. But you may always use pass-by-reference instead to avoid this.

      This method is used for subroutines without a prototype. It is also used for any subroutine called with an & and … ?.

    • Argument processed after each other
    • The arguments are separated by the commas in the source code. The arguments are processed one after each other. The processing is done in either scalar or list context.

      This method is used for subroutines with a prototype. The prototype defines which context is used.

      It is also used for built-in functions described in perlfunc.

    Proposals to add this before A return statement may :

    The return value is a flat list of scalar values, if the subroutine is called in list context and single one in scalar context. To avoid flattening of arrays or hashes you must use pass-by-reference.

    Documentation of split

    Proposals to add this in the beginning of split

    Split is a built-in function (implemented in the Perl interpreter and not as a Perl sub).

    The arguments are processed consecutively and in scalar context. The result of the processing of /PATTERN/ is a compiled regular expression. It is later used to match the separators. If LIMIT is one it is not used.

      I would reword "the call of the subroutine definition" - the definition isn't called, the definition is parsed and compiled to ops, and then this compiled thing is called. But as a non-native speaker of English, I don't dare to guess how to formulate that to make it easy to understand for newcomers.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        I have the same problem!
      Icky. Examples beat words

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11121004]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2022-05-26 14:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you prefer to work remotely?



    Results (93 votes). Check out past polls.

    Notices?