Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Seekers of Perl Wisdom

( #479=superdoc: print w/replies, xml ) Need Help??

If you have a question on how to do something in Perl, or you need a Perl solution to an actual real-life problem, or you're unsure why something you've tried just isn't working... then this section is the place to ask. Post a new question!

However, you might consider asking in the chatterbox first (if you're a registered user). The response time tends to be quicker, and if it turns out that the problem/solutions are too much for the cb to handle, the kind monks will be sure to direct you here.

User Questions
Pointers and References
8 direct replies — Read more / Contribute
by Leudwinus
on Nov 22, 2020 at 20:55

    Fellow Monks,

    I am still trying to wrap my head around pointers/references in Perl. I came up with the following program to help me better understand but was hoping you could please help me with some questions.

    use warnings; use strict; use v5.10; my $variable = 22; my $pointer = \$variable; say "The address of \$varible, which contains the value $variable,"; say "is $pointer"; $$pointer = 25; say "Look at that! \$variable now equals $variable"; sub sum_and_diff { my $a = shift @_; my $b = shift @_; my $res = \(shift @_); # why does the "\" work here? my $sum = $a + $b; $$res = $a - $b; return $sum; } my $b = 2; my $diff; # this is line 27 my $pointer_to_diff = \$diff; say "the sum of 5 and $b is ", &sum_and_diff(5, $b, $pointer_to_diff); say "and the difference is ", $pointer_to_diff; say "the sum of 9 and $b is ", &sum_and_diff(9, $b, \$diff); say "and the difference is ", $diff; # this is line 34

    (1) Does the backslash ("\") in the my $res line mean that $res contains the address of the third argument passed to the function? I think so but just wanted to confirm.

    (2) Does the "double dollar sign" ("$$") two lines later mean to put the value of the difference of $a and $b in the memory location that is $res?

    (3) Why do the lines using $pointer_to_diff work but the last two lines using \$diff and $diff not work? I thought that these lines were essentially equivalent and that $diff was defined in line 27. Instead, I get the following output:

    The address of $varible, which contains the value 22, is SCALAR(0x801e64540) Look at that! $variable now equals 25 the sum of 5 and 2 is 7 and the difference is 3 the sum of 9 and 2 is 11 Use of uninitialized value $diff in say at line 34. and the difference is

    Gratias tibi ago
    Leudwinus

    Edited to add: I thought using ${\$diff} in the last line would work but that too gave me the same error.

Multi-dimensional constants
6 direct replies — Read more / Contribute
by Ionic
on Nov 22, 2020 at 00:44

    I'm trying to create a read-only "multi-dimensional" constant using the built-in constant pragma. I know that there's the Readonly module (amongst others), but I'm trying to stick to basics.

    Using anonymous list references doesn't really work, because they can be modified, as documented:

    Even though a reference may be declared as a constant, the reference may point to data which may be changed, as this code shows.
    use constant ARRAY => [ 1,2,3,4 ]; print ARRAY->[1]; ARRAY->[1] = " be changed"; print ARRAY->[1];

    Okay, so I'll use some sort of indirection, I thought, and came up with something like this:

    use strict; use warnings; use Data::Dumper; use constant INVALID_DATA => ( q{invalid}, 0 ); use constant ADD_DATA => ( q{add}, 1 ); use constant REMOVE_DATA => ( q{remove}, 2 ); use constant MODES => ( \&ADD_DATA, \&REMOVE_DATA ); print {*STDERR} "Dumping MODES: " . Dumper ((MODES)); 1;
    … but, this doesn't quite do what I expected. Output:
    Dumping MODES: $VAR1 = sub { "DUMMY" }; $VAR2 = sub { "DUMMY" };
    I was under the impression that constants are really subs that I could take the reference of, but this doesn't seem to be the case.

    Alternatively, I've tried taking direct references, but this is... just merging the lists (which is obviously bad to begin with and what I wanted to avoid by using references) in a weird "reference all elements individually" way:

    use constant MODES => ( \ADD_DATA, \REMOVE_DATA );
    leading to
    Dumping MODES: $VAR1 = \'add'; $VAR2 = \1; $VAR3 = \'remove'; $VAR4 = \2;

    Is there any proper way to do this?

What's the right way to write a method which returns one line at a time from a file?
4 direct replies — Read more / Contribute
by Cody Fendant
on Nov 21, 2020 at 23:21

    I want to write a module such that I can do this with a certain file:

    use MyModule; my $reader = MyModule->new(); ### MyModule opens a file behind the scenes while(my $line = $reader->get_next_line()){ print "here's the next line: $line\n"; } ### stop when we get to the end of the file, obviously

    That is, keep the file handle open in the module and each time I call get_next_line() get one more line.

    Clearly I can't keep re-opening the file every time. Do I use a module like Tie::File?

    Thanks in advance.

file test results not as expected
2 direct replies — Read more / Contribute
by navalned
on Nov 21, 2020 at 17:44

    I'm trying to push all executibles in my $PATH to an array, but doesn't seem to work as expected.

    use IO::Dir; my @cmds; my @paths = split /\:/, $ENV{PATH}; foreach my $path (@paths) { tie my %dir, 'IO::Dir', $path; foreach my $file (keys %dir) { if (-f -x $file) { push @cmds, $file; } } undef %dir; } foreach my $cmd (@cmds) { print $cmd . "\n"; }

    Here is the output I'm getting:

    h2xs

    I guess its kinda cool it found a perl related executable, but I was hoping for more.
    Edgar

ConfigMap error in dancer-ex on OpenShift 4.5
No replies — Read more | Post response
by elfner
on Nov 21, 2020 at 13:51

    Hi - using dancer-ex from github with Openshift 4.5, my pod blows up when adding a ConfigMap.

    The error shows as:

    $ oc logs -f dancer1-7cc875b4b6-k6kkn
    Sat Nov 21 17:46:07.425660 2020 so:warn pid 1 AH01574: module perl_module is already loaded, skipping
    AH00526: Syntax error on line 46 of /opt/app-root/etc/httpd.d/env.conf:
    PerlPassEnv takes one argument, PerlPassEnv
    

    The ConfigMap file itself is trivial:

    $ cat filterPatterns 
    pattern1=foo
    pattern2=bar
    

    Anyone have any tips for doing this successfully? (i.e. leverage Kubernetes ConfigMaps with a Perl Dancer framework app)

    Appreiciate any insight - thanks.
Scraping Javascript page using perl
3 direct replies — Read more / Contribute
by Bpl
on Nov 21, 2020 at 09:39
    Hi Monkers, Actually I am trying to scrape the Javascript code of an Italian website, I am able to scrape the normal HTML code through the classical
    $lwp->get( $site );

    But I cannot scrape the DOM code created by Javascript (or Ajax), any helps??

    I have already tried with the "get" function of WWW::Mechanize::PhantomJS but it doesn't work.

    the site is: http://operedigitali.lincei.it/rendicontiFMN/cliccami.htm under the voice of "volumi"

    Thanks in advance.
Script fails to insert text and appends it towards the end of file.
4 direct replies — Read more / Contribute
by always_coys
on Nov 21, 2020 at 07:40
    Hi Monks,

    I am trying to automate the running of a finite element program using a Perl script. It requires me to copy a block of text (each line starting with the same keyword) and insert it to a second file, at a particular line number. There is text in the second file, before and after this line number. With help from the Monks, I was able to update my script. However, I am noticing that the script is simply appending to the output file, rather than inserting the block of text to the desired line number.

    The input file is given below. I am trying to copy the lines beginning with the keyword NODE and inserting it in the output file, at line number 37. Basically, I am trying to append to a section of the output file (to lines containing the same keyword). I have left sufficient space in the output file for inserting text from the input file.

    NODE 32 0.00000 0.00000 -1.90000 NODE 33 0.00000 0.00000 -5.50000 NODE 34 0.00000 0.00000 -9.00000 NODE 35 0.00000 0.00000 -15.00000 NODE 36 0.00000 0.00000 -18.90000 NODE 37 0.00000 0.00000 -22.40000 NODE 38 0.00000 0.00000 -25.90000 NODE 39 0.00000 0.00000 -29.00000 NODE 40 0.00000 0.00000 -32.50000 NODE 41 0.00000 0.00000 -33.90000 NODE 42 0.00000 0.00000 -62.90000 BEAM 26 27 26 1 14 1 BEAM 27 28 27 1 13 1 BEAM 28 29 28 1 12 1 BEAM 29 30 29 1 11 1

    The output file is given below.

    'Node ID X Y Z BC NODE 1 4.51000 0.00000 79.00000 NODE 2 0.00000 0.00000 79.00000 NODE 3 0.00000 0.00000 78.27000 NODE 4 -1.88000 0.00000 78.27000 NODE 5 0.00000 0.00000 76.80000 NODE 6 0.00000 0.00000 74.46000 NODE 7 0.00000 0.00000 71.66000 NODE 8 0.00000 0.00000 68.86000 NODE 9 0.00000 0.00000 66.07000 'Elem ID np1 np2 material geom lcoor ecc1 BEAM 1 2 1 2 36 2 BEAM 2 3 2 2 36 1 BEAM 3 3 4 2 36 2 BEAM 4 5 3 2 36 1 BEAM 5 6 5 3 35 1 BEAM 6 7 6 3 34 1 PIPE 19 4.489 0.022 PIPE 20 4.488 0.021 PIPE 21 4.487 0.020 PIPE 22 4.395 0.018 PIPE 23 4.351 0.018 PIPE 24 4.261 0.017

    My script below, should ideally place the block of text beginning with NODE from the input file, on line number 11 of the output file (i.e. just below another block of text that begins with NODE. However, my script is simply appending the text to the output file (after counting 11 lines from the end). Could the Monks please help me identify what went wrong?) Thanks a lot (always_coys).

    use strict; use warnings; # use the Tie::File option use Tie::File; my @records; tie @records, 'Tie::File', "output.fem"; my $in_file = "fake_vals.fem"; my $outIndex = 11; # use three parameter open '<' - read mode open my $in, '<', "$in_file" or die "cannot open '$in_file' for readin +g: $!\n"; while (my $line = <$in>) { next if $line !~ /\bNODE\b/i; chomp $line; $records[$outIndex] = $line; ++$outIndex; }
help with versioning modules
6 direct replies — Read more / Contribute
by Special_K
on Nov 20, 2020 at 12:08

    I am trying to incorporate version numbers into modules that will only be used internally and cannot get it to work. As a basic testcase, I have the following file Foo.pm, located at '/home/user/perl_modules/lib/perl5/My/Foo.pm':

    package Foo; our $VERSION = '1.0'; use strict; use warnings; sub new { my $class = shift(); my ($arguments) = @_; my $self = {}; bless $self, $class; }

    I also have the following script, foo_version_test.pl, used to test the version number of Foo.pm:

    #!/tool/bin/perl -w use strict; use lib '/home/user/perl_modules/lib/perl5'; use My::Foo 1.0; printf("version = %s\n", $Foo::VERSION);

    Running the script produces the following output:

    My::Foo defines neither package nor VERSION--version check failed at . +/foo_version_test.pl line 4. BEGIN failed--compilation aborted at ./foo_version_test.pl line 4.

    I'm not sure what's going wrong here given that both the package and VERSION statements exist in Foo.pm.

    On a related note, if I have modules that will only be used internally and that I want to version (as opposed to modules I download from CPAN, in which subsequent module updates overwrite the previous module version), suppose I have the following directory structure:

    /home/user/perl_modules/lib/perl5/My/FooVersion 1.0/ Foo.pm 1.1/ Foo.pm 1.2/ Foo.pm Devel/ Foo.pm

    How would I use a particular version of Foo.pm in my script? Perl is fine with:

    use My::FooVersion::Devel::Foo;

    but trying to reference any of the numbered versions in the same manner, even when I quote either the numerical portion or the entire string, produces syntax errors. For example, none of the following work:

    use My::FooVersion::1.1::Foo; use "My::FooVersion::1.1::Foo"; use My::FooVersion::"1.1"::Foo; use My::FooVersion::'1.1'::Foo; use 'My::FooVersion::1.1::Foo';
Filehandle/array naming
3 direct replies — Read more / Contribute
by JSAWS
on Nov 20, 2020 at 06:07
    been really struggling here.... probably a dumb approach

    so I have 3 files, file1,file2,file3 generated by filehandles over ssh. File are written on local machine and contain CSV data coming from 6 nodes (need to stay like this). My script works but I am trying to optimize with a foreach loop on each of the files rather than hard coded for each.

    so I have this array:
    @FILES = ( 1, 2, 3 ); foreach $FILE (@FILES) { # Open filehandle tailing file written by ssh<br><br> open ( ${fh.$FILE}, "tail -f file$FILE |") || die "can't open file$ +FILE"; while ( ${line.$FILE} = ${fh.$FILE} ) { # Here I do my split on the CSV line and assign to arrays (keepi +ng the # $FILE value as a suffix to the array name)<br><br> @{fields.$FILE} = split(/,/,${line.$FILE}); push @{AAA.$FILE}, ${fields.$FILE[0]}; # .....

    The issue I have is that ${line.$FILE} does not seem to be filled by the filehandle, I get the mem address (GLOB(0x563b358e1060) for example).

    any help greatly appreciated!

Fastest way to "pick without replacement"
5 direct replies — Read more / Contribute
by haukex
on Nov 20, 2020 at 05:14

    Today's post "Find combination of numbers whose sum equals X" got me wondering about this: what's the "best" (= fastest, most memory-efficient, etc.) way to implement a (typically recursive) "pick without replacement" algorithm like this? Here's an example with splice, plus grepping the indicies, as choroba used here. Who has more ideas?

    use warnings; use strict; use Benchmark qw/cmpthese/; my @numbers = ( 0..20 ); my $index = 3; my @expect = ( 0..2,4..20 ); use constant TEST => 0; cmpthese(-2, { splice => sub { my @output = @numbers; splice @output, $index, 1; join("\0", @output) eq join("\0", @expect) or die if TEST; }, grep => sub { # https://www.perlmonks.org/?node_id=11123877 my @output = @numbers[ grep $_ != $index, 0 .. $#numbers ]; join("\0", @output) eq join("\0", @expect) or die if TEST; }, }); __END__ Rate grep splice grep 835107/s -- -68% splice 2575950/s 208% --

Add your question
Title:
Your question:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":


  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others rifling through the Monastery: (4)
    As of 2020-11-27 08:12 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found

      Notices?