Data-Rlist

 view release on metacpan or  search on metacpan

lib/Data/Rlist.pm  view on Meta::CPAN

    $ perl -e 'print "nope" unless defined *foo{HASH}'
    nope
    $ perl -e 'print *foo{SCALAR}'
    SCALAR(0x1002e94c)

In Perl5 it is still not possible to  get a reference to an I/O-handle (file-, directory- or socket
handle) using  the backslash operator.  When a  function requires an I/O-handle  you must therefore
pass a globref.  More precisely, it is possible to pass an F<IO::Handle>-reference, a typeglob or a
typeglob-ref as the filehandle.  This is obscure bot only for new Perl programmers.

    sub logprint($@) {
        my $fh = shift;
        print $fh map { "$_\n" } @_;
    }

    logprint(*STDOUT{IO}, 'foo');   # pass IO-handle -> IO::Handle=IO(0x10011b44)
    logprint(*STDOUT, 'bar');       # ok, pass typeglob-value -> '*main::STDOUT'
    logprint(\*STDOUT, 'bar');      # ok, pass typeglob-ref -> 'GLOB(0x10011b2c)'
    logprint(\*STDOUT{IO}, 'nope'); # ERROR -> won't accept 'REF(0x10010fe0)'

It is very amusing that Perl, although refactoring  UNIX in form of a language, does not make clear
what a file-  or socket-handle is.  The  global symbol STDOUT is actually  an F<IO::Handle> object,
which F<perl>  had silently  instantiated.  To functions  like F<print>,  however, you may  pass an
F<IO::Handle>, globname or globref.

B<VIOLATING STASHES>

As we saw we can access the Perl guts without using a scalpel.  Suprisingly, it is also possible to
touch the stashes themselves:

    $ perl -e '$x = 42; *x = $x; print *x'
    *main::42

    $ perl -e '$x = 42; *x = $x; print *42'
    *main::42

By assigning the scalar value F<$x> to F<*x> we have demolished the stash (at least, logically):
neither F<$42> nor F<$main::42> are accessible.  Symbols like F<42> are invalid, because 42 is a
numeric literal, not a string literal.

    $ perl -e '$x = 42; *x = $x; print $main::42'

Nevertheless it is easy to confuse F<perl> this way:

    $ perl -e 'print *main::42'
    *main::42

    $ perl -e 'print 1*9'
    9

    $ perl -e 'print *9'
    *main::9

    $ perl -e 'print *42{GLOB}'
    GLOB(0x100110b8)

    $ perl -e '*x = 42; print $::{42}, *x'
    *main::42*main::42

    $ perl -v
    This is perl, v5.8.8 built for cygwin-thread-multi-64int
    (with 8 registered patches, see perl -V for more detail)

Of course these  behaviors are not reliable, and  may disappear in future versions  of F<perl>.  In
German  you  say   "Schmutzeffekt"  (dirt  effect)  for  certain   mechanical  effects  that  occur
non-intendedly,  because machines  and electrical  circuits are  not perfect,  and so  is software.
However, "Schmutzeffekts" are neither bugs nor features; these are phenomenons.

B<LEXICAL VARIABLES>

Lexical variables (F<my> variables) are not stored in stashes, and do not require typeglobs.  These
variables are stored in a special array, the F<scratchpad>, assigned to each block, subroutine, and
thread. These are really private variables, and they cannot be F<local>ized.  Each lexical variable
occupies a  slot in the scratchpad;  hence is addressed by  an integer index, not  a symbol.  F<my>
variables are like F<auto> variables in C.  They're also faster than F<local>s, because they can be
allocated at compile time, not runtime. Therefore you cannot declare F<*x> lexically:

    $ perl -e 'my(*x)'
    Can't declare ref-to-glob cast in "my" at -e line 1, near ");"

Seel also the Perl man-pages L<perlguts>, L<perlref>, L<perldsc> and L<perllol>.

=head3 C++

In C++  we use a  F<flex>/F<bison> scanner/parser combination  to read Rlist  language productions.
The  C++  parser  generates  an   F<Abstract  Syntax  Tree>  (AST)  of  F<double>,  F<std::string>,
F<std::vector> and F<std::map> values.   Since each value is put into the  AST, as separate object,
we use a free store management that allows the allocation of huge amounts of tiny objects.

We also use reference-counted smart-pointers, which allocate themselves on our fast free store.  So
RAM will not be fragmented, and the allocation of RAM is significantly faster than with the default
process heap.   Like with Perl,  Rlist files can  have hundreds of megabytes  of data (!),  and are
processable in constant time, with constant  memory requirements.  For example, a 300 MB Rlist-file
can be read from a C++ process which will not peak over 400-500 MB of process RAM.

=head1 BUGS

There are no known bugs, this package is stable.  Deficiencies and TODOs:

=over

=item *

The C<"deparse"> functionality for the C<"code_refs"> L<compile option|/Compile Options> has not
yet been implemented.

=item *

The C<"threads"> L<compile option|/Compile Options> has not yet been implemented.

=item *

IEEE 754 notations of Infinite and NaN not yet implemented.

=item *

F<L</compile_Perl>> is experimental.

=back

=head1 COPYRIGHT/LICENSE



( run in 0.672 second using v1.01-cache-2.11-cpan-39bf76dae61 )