Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

The Monastery Gates

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

Donations gladly accepted

If you're new here please read PerlMonks FAQ
and Create a new user.

New Questions
Can I ask Perl if an object will stringify?
4 direct replies — Read more / Contribute
by haukex
on Mar 29, 2015 at 13:16

    Hello everyone,

    I seek your wisdom on this question: Is there a way to ask Perl whether an object supports stringification, including via "magic autogeneration"? The only way I've found so far was by trying to eval the stringification, like in the code below. The specific case here is the "ICanStringify" class, where overload::Method($s,'""') is false, but the object still stringifies. Did I miss some function somewhere that can tell me whether that class will stringify?

    #!/usr/bin/perl use strict; use warnings; { package OnlyAString; use overload fallback=>0, '""'=>sub { ${shift()} } } { package ICanStringify; use overload fallback=>undef, '0+'=>sub { ${shift()} } } { package OnlyANumber; use overload fallback=>0, '0+'=>sub { ${shift()} } } bless my $s1=\do {my $x=111}, 'OnlyAString'; bless my $s2=\do {my $x=222}, 'ICanStringify'; bless my $s3=\do {my $x=333}, 'OnlyANumber'; can_str($s1); can_str($s2); can_str($s3); use overload (); sub can_str { my $s = shift; print "Object ", overload::StrVal($s), ":\n"; print " \"\" ", overload::Method($s,'""') ?"IS":"is NOT", " overloaded\n"; my $e = eval { "$s" }; print " stringification ", defined($e) ?"WORKED: $e\n":"DIDN'T work: $@\n"; }

    Output:

    Object OnlyAString=SCALAR(0x3684370): "" IS overloaded stringification WORKED: 111 Object ICanStringify=SCALAR(0x3664210): "" is NOT overloaded stringification WORKED: 222 Object OnlyANumber=SCALAR(0x3679682): "" is NOT overloaded stringification DIDN'T work: Operation """": no method found, argu +ment in overloaded package OnlyANumber at test.pl line 28.

    The background is that I have a function that accepts only strings. Because passing a reference was a mistake I made a few times, I started warning if any references were passed to it, including objects. But then I realized that some objects stringify and that's useful, and that some objects die when you try to stringify them. I'd like to loosen the restrictions, and still warn on references and objects that don't stringify, but not on objects that stringify.

    Any wisdom on this topic would be greatly appreciated!

Perl reference array
4 direct replies — Read more / Contribute
by teun-arno
on Mar 28, 2015 at 16:57
    I have a question about the following :
    use Data::Dumper; # it seems that ', ,' in the third record is not producing a index in +the array. $arr= [ [1,2,3,4,5,6,7,8,9 ], #works as expected [1,2,3,'',5,6,7,'',9 ], #works as expected [1,2,3, ,5,6,7, ,9 ], #does not work as expected "empty fields " + are ignored ]; my $dd=Data::Dumper->new([$arr],[ qw(arr) ] )->Indent(1)->Quotekeys(0) +->Dump; print $dd; $str_arr=q`$arr= [ [1,2,3,4,5,6,7,8,9 ], [1,2,3,'',5,6,7,'',9 ], [1,2,3, ,5,6,7, ,9 ], ];` ; print "\n\n"; print $str_arr ; $str_arr=~ s/,\s*,/,'',/g; # filling in the empty fields print $str_arr ; $arr = undef; $arr = eval $str_arr; my $dd=Data::Dumper->new([$arr],[ qw(arr) ] )->Indent(1)->Quotekeys(0) +->Dump; print $dd; # this seems to work, next question is : The original $arr is send to +a subroutine. # How to stringify that in the subroutine without hardcoding this. ( a +s I have done in the above ) ! #
    Thanks for your time dear perl monks.
What is (a => b => c) ?
4 direct replies — Read more / Contribute
by philgoetz
on Mar 26, 2015 at 15:29

    What does this do?

    @x = (a => b => c);

    There's a lot of that in the program I'm looking at. As far as I can tell, it's the same as

    @x = (a, b, c);
XML::CSV out of memory
3 direct replies — Read more / Contribute
by slugger415
on Mar 26, 2015 at 12:03

    Hello, I am using XML::CSV to parse a very large (500MB) CSV file and convert it to XML. I keep getting an "out of memory" error during the parse.

    Is there a way to "purge" data to free up memory during this process, like you can with XML::Twig? (Though I don't see anything about handlers in the doc....)

    FWIW:

    my $csv_obj = XML::CSV->new( error_out => 1 ); $csv_obj->{column_headings} = \@heads; my $status = $csv_obj->parse_doc($file);

    thanks!

Beginner here - basic help
3 direct replies — Read more / Contribute
by xr6turbo
on Mar 26, 2015 at 09:09

    Hey Monks, Just starting off in perl (and programming in general) and need to do an exercise but a bit confused on the process.

    Trying to create a script that will ask the user to enter a number between 1 and 5 and for it to print a colour represented e.g. if they enter 1, Blue comes up or 3, red gets printed. I've done a bit of research and I know I need to create an array (@) but not too clear on how to do so.

    After that I need to assign an emotion to the colour e.g. blue = calm, red = angry. I'd also like to know how to incorporate modulus into this so on even/odd number inputs I can print it out (think ill need an if/else statement for this?)

    At the end I'd like it to look like this:

    Please enter a number between 1 and 5:

    1

    Blue. Even. Calm

    So far I've got the code below and have no idea how to finish or even progress, any ideas?

    print "Please enter a number between 1 and 5 (inclusive) below:"; my $number = <STDIN>; chomp($number); my @colours = ("red", "green", "blue", "purple", "black"); my %table = ( 1 => "angry" 2 => "sick" 3 => "calm" 4 => "worried" 5 => "sad" );
Module::Build's adding new filetypes in ExtUtils::MakeMaker
4 direct replies — Read more / Contribute
by vicdan
on Mar 25, 2015 at 13:22

    Hi there,

    as Module::Build will vanish out of the perl core in some versions, I'd like to know how I can do Module::Buildīs adding of new file types.

    Say I have .dat files that are located in /dat in my modules path.

    With Module::Build I can add a file type by adding my files within the definition ( dat_files => {'some/dir/Bar.dat' => 'lib/Foo/Bar.dat'},), then make that known to the builder:

    $build->add_build_element('dat');

    Is there anything similar in ExtUtils::MakeMaker?

    I searched for that feature but is was not really obvious to me ...

[OT] The interesting problem of comparing bit-strings.
10 direct replies — Read more / Contribute
by BrowserUk
on Mar 24, 2015 at 04:08

    The interesting problem of comparing bit-strings.

    Perl's vec and bitwise string operators are very useful and powerful for manipulating (large) bitstrings; but they are limited in several ways.

    Namely, there are no left & right shift operators for them; and the bitwise string operators operate with 8-bit boundaries.

    One common operation needed for programming with bitstrings is the ability to search one bitstring for another bitstring, looking for matches that occur even at non-byte or integer-sized alignments.

    So graphically, using 8-bit units instead of 64 for brevity, the problem is this:

    Find (the first occurance of):

    needle = x1001010 10101001 10100xxx (x represents bits we are not + interested in)

    in:

    haystk = xxxxx001 10001101 01110010 10101010 01101001 01100011 100 +11001 00010001 .....

    The specification of needle requires three values:

    • *ndl : points to the first unit (8-bits above, 64-bits in reality) of the bitstring to find.
    • oNdl : the offset, in bits, into the first unit, of the needle.
    • lNdl : the length in bits of what we are looking for.

    Similarly, the haystack requires 3 values:

    • *hay : the address of the first unit of the bitstring to search.
    • oHay : the offset, in bits, into the first unit of the haystack.
    • lHay : the length, in bits, of the haystack.

    The function required thus takes six arguments:

    U64 bsSearch( U64 *hay, U8 oHay, U64 lHay, U64 *ndl, U8 oNdl, U64 +lNdl ) { ... }

    Return value

    In an ideal world (Perl) the function would return the unit number(or address), and the offset into that unit, where the match is found (or 0).

    As C doesn't permit multiple return values, I've opted for a single 64-bit value indicating the offset from the start of the first unit of the haystack (or -1?).

    Found:

    haystk = xxxxx001 10001101 01110010 10101010 01101001 01100011 100 +11001 00010001 ..... needle = x10010 10101010 0110100x xx (note the + alignment change!) return = 01234567 89012345 6789 = 19th bit = unit 2/ bit 3

    There are 128-bit shift instructions available on Intel/AMD 64-bit processors (and probably most others):

    REX.W + 0F A5 SHLD r/m64, r64, CL B Valid N.E. Shift + r/m64 to left CL places while shifting bits from r64 in from the rig +ht. REX.W + 0F AD SHRD r/m64, r64, CL B Valid N.E. Shift + r/m64 to right CL places while shifting bits from r64 in from the le +ft.

    which are available on the MS compiler as intrinsics:

    unsigned __int64 __shiftleft128( unsigned __int64 LowPart, unsigne +d __int64 HighPart, unsigned char Shift ); unsigned __int64 __shiftright128( unsigned __int64 LowPart, unsign +ed __int64 HighPart, unsigned char Shift );

    and probably in gcc (though I couldn't locate the names).

    Using these, you can load two registers with two units of one of the bitstrings and when shifting the first register, bits from the second are shifted in.

    Thus to process through the bitstrings 1 bit at a time, you use loops something like:

    for( i = 0; i < ( lHay % 64 )+1; ++i ) { r1 = *( hay + i ); r2 = *( hay + i + 1 ); for( b1 = 0; b1 < 64; ++b1 ){ __shiftleft128( r2, r1, 1 ); } }

    and:

    for( j = 0; j < ( lNdl % 64 )+1; ++j ) { r3 = *( ndl + j ); r4 = *( ndl +j + 1 ); for( b2 = 0; b2 < 64; ++b2 ) { __shiftleft128( r4, r3, 1 ); } }

    Except that:

    1. the terminating conditions of the outer loops need work; (especially in light of b below).
    2. the initialisation/repopulation of the two registers needs to take account of the bit offsets oHay & oNdl respectively.
    3. the two loops need to run concurrently; with the second loop resetting to the starting condition everytime r1 != r3;
    4. We might successfully match & advance through several units before hitting a mismatch.

      At which point we not only need to reset the needle (inner pair?) loop;

      we also need to reset the hay loop by the distance we successfully advanced before the failure, then advance one bit.

    What have I tried so far?

    In answer to the traditional question: You've just pretty much read it!

    The function definition and a few local variables:

    U64 bsSearch( U64 *hay, U8 oHay, U64 lHay, U64 *ndl, U8 oNdl, U64 +lNdl ) { register U64 r1, r2, r3, r4; U64 i, j, rv; U8 b1, b2; ... return rv; }

    And the two separate loops above, and little else, despite many hours of though and scribbling on post-its.

    I suspect that the right approach might include another subroutine that compares the needle to the haystack at a given, fixed offset; but I'm stuck for how to code that such that it doesn't repeatedly shift one or both by an increasing number of bits each time it is called?

    I also thought that it might make sense to copy the needle to an aligned chunk of memory, to eliminate its offset from the problem; but it could be a very large piece of memory, which would be expensive.

    Update:I suspect one or even two gotos may be needed; though I'd avoid them if I can.

    What am I looking for?

    Cluebats; pseudo-code; real-code of any flavour.

    Basically anything that will make the penny drop as to how to code this beast?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Perl Module API update or new release
2 direct replies — Read more / Contribute
by VinsWorldcom
on Mar 23, 2015 at 13:45

    Monks,

    I maintain a CPAN module Cisco::Management which I wrote / released when I was just learning how to write modules. Needless to say, there is much room for improvement and I've decided to break the monolithic code into sub-modules under the main Cisco::Management grouping.

    This requires that I change the current API slightly:

    Instead of "use Cisco::Management", it'll be "use Cisco::Management::MODULE"

    So I thought I'd take the opportunity to standardize and change existing accessor calls as well as add all the missing ones.

    I made note of this in the latest release (0.08) saying it was the last in this line / format. Not sure who actually reads the README / POD.

    QUESTIONS

    • Should my next release be under the same namespace (Cisco::Management) with initial backward compatibility (warnings) for the new API?
    • Should I release the new version under a new namespace (Cisco::Management2, Cisco::SNMP, etc)?
    • Any recommendations / previous experience to share?

    I don't want to clutter the namespace, abandon a module and start a new one if there is no need. I don't know how many people use this (I'm guessing very few) so impact may be minimal as long as backward compatibility is maintained for the first new API version release.

Parsing a Formatted Text File
6 direct replies — Read more / Contribute
by Pharazon
on Mar 23, 2015 at 10:40
    I have a set of data that I need to parse into a csv file. The data looks like the following:
    06 01720168-00000000257980 123 S Somewhere HWY 192 172016-8 Company NATURAL GAS CO., INC. Business P O BOX 1547 123 Road Dr. Town ST 12345 SUITE# 1234 Town, ST 12345 6/23/2014 $257.98 Business 6/23/2014 123 S Road HWY 123 172016-8 6/09/2014 Town ST 12345 $257.98 02CS 4/30 5/28 3117.0 3259.0 142.0 Meter # C204508 142.0 232.99 Pipe Replacement Pgm SNR Comm 3.27 RESEARCH & DEVELOPMENT TARIFF .03 3.00% Rate Increase County Co Sc Tax on 236.29 7.09 6.00% State Tax on 243.38 14.60 Current Charges 257.98 Previous Amount Due 351.60 Payment Received 5/22 351.60CR Total Amount Due 257.98 1-877-123-4567 66.0 28 142.0 8:00am to 4:00pm 58.6 30 203.0 70.3 28 174.0

    The file has one record per 58 lines. I can handle the fine parsing that will need to happen on the lines to pull out the variables but what I am having trouble wrapping my head around is a method for grabbing 58 lines at a time and then performing the necessary processes on each iteration. For example once I have the 58 lines read in I know that line 8-11 from position 1-39 contain the return address that I will be putting as "return1","return2","return3","return4" in the CSV file. This is going to happen on every record as well as each of the other pieces I need to parse.

    I thought about just using a counter and resetting it after every 58 lines while looping through the entire file but that didn't seem like it would be the best solution. As I'm by no means an expert at perl I wanted to check here with you guys to see if anyone has a better place to start or some ideas on how to make this a bit more clean and efficient.

    If you need any other information please let me know.

    UPDATE: I found a control character other than newline in the data at the beginning of each record. I was able to use local $/ = "\014"; (was looking for newlines or double newlines and not this character) to pull the data into a variable one record at a time. I then split the data using my @lines = split /\n/, $record; into an array with one line per.

    So now I believe I can pass the array to a subroutine, perform the checks and changes I need to on each of the lines, write the line out to a csv file and then move to the next record.

substract from actual date 7 days and printout in month.days.hours.min.year
3 direct replies — Read more / Contribute
by nicopelle
on Mar 23, 2015 at 06:06
    Hi to all, I need to substract from actual date/time 7 days. The format could be for example #031810002015 (march 18 10:00 of year 2015):
    #!/usr/bin/perl -w #output as 031810002015 (march 18 10:00 del 2015) ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); my $now = sprintf("%02d%02d%02d%02d%04d", $mon+1, $mday,$hour, $min,$y +ear+1900); print "$now\n";
    Thanks for your time as usuals, Nick.
New Meditations
RFC: Automatic logger module
2 direct replies — Read more / Contribute
by balajiram
on Mar 23, 2015 at 22:51
    I have written a Perl module that redirects the the output of STDOUT and STDERR to a file very easily. For example:
    use Auto::Log; my $log = new Auto::Log, "some.log"; ...Write some code here... print "INFO: This gets printed to the log file" $log->DESTROY;

    One could also use the log file in tee mode using a simple option.

    I wanted to hear from users as to how they feel about this. What do you think? Do you think you'd like to use such a Perl module?

    The principal use of this module is that all that a user ever needs to do is to use the print, or warn statements. One doesn't have to open a new file using open() or anything. In my opinion this saves effort for a regular programmer who wants to get code written fast.

    Let me know what you think though.

    Also, please do give some suggestions for the module name. Do you like the name 'Auto::Log'?

    Balaji

New Cool Uses for Perl
"Spritz" crypto algorithm
No replies — Read more | Post response
by RonW
on Mar 24, 2015 at 16:41

    For testing purposes, I implemented Rivist's new crypto algorithm in Perl. It is a proposed replacement for his (once very popular) RC4 algorithm. Thought there might be some curiosity value to it.

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 romping around the Monastery: (6)
As of 2015-03-30 01:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When putting a smiley right before a closing parenthesis, do you:









    Results (632 votes), past polls