Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
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
Object accessors with unknown data
5 direct replies — Read more / Contribute
by Amblikai
on Jan 26, 2015 at 05:43

    Hi Monks! I have a quick question with regards to building objects. My search keeps bringing up references to Moose et al, but i don't want to use an external object system. I'm practicing OOP with bog standard perl for my own education!

    With that in mind, i'm writing a program where i'm not going to know the data i have when constructing the object. In the past i've always known the name and type of each attribute so i can construct accessors and methods to check that the attribute data is correct etc.

    Now i'm stuck though! How do you write accessors for unknown attributes?

    Thanks!

NDBM problem
1 direct reply — Read more / Contribute
by RuntimeError
on Jan 26, 2015 at 05:26
    Dear Monks,

    I have RedHat 6 and Perl 5.10 shipped with it. Since a recent update NBDM fails: in my case it is an errno 17 (more precise: it is Term::Clui database that is called and fails with the ndbm error). The database was created with the correct rights, etc. and the exact same program worked correctly until the update of the system.
    Do you know which might be the trouble here? Any dependencies I don't know about? I dont have much information for you but any hint is highly appreciated.
    I can disable the database in Term::Clui that is not my real concern.
    I am worried that the whole database mechanism in Perl might be broken...

    PS: I am using version 1.8 of gdbm (the latest version according to yum).
Scrambling help
3 direct replies — Read more / Contribute
by Anonymous Monk
on Jan 25, 2015 at 15:46

    a couple of days ago i asked tou guys here for help and you delivered like gods so here i am again with another problem so pls help

    Write a script which will do a simple scrambling of a string. The script should have variables for the original string (eg $message) and a number (eg $number) (which should be less than the length of the string). The scrambling should be achieved by reversing the first and last $number characters of $string (in that order). To avoid giving any hints as to the values used the scrambled string should appear all in lowercase.

    For example:

    String=Babraham Number=2, Scrambed= abbrahma String=Institute Number=3, Scrambled=snititetu

    Hint: use the substr() and reverse() functions.

pl c sv text format wrap
4 direct replies — Read more / Contribute
by edrew04
on Jan 25, 2015 at 04:36

    Hi can you help me on creating a pl of c sv text format example:

    AMS.csv

    1,Go,Manuel,V.,1/22/2015,8:30AM,5:30PM,1001 2,Calinisan,Peter,S.,1/22/2015,8:30AM,5:30PM,1002 3,Sioting,Michael,S.,1/22/2015,8:30AM,5:30PM,1003

    After running the ksh wrapper it should become like this:

    2002,Go,Manuel,V.,1/22/2015,8:30AM,5:30PM,IT 2001,Calinisan,Peter,S.,1/22/2015,8:30AM,5:30PM,HR 2003,Calinisan,Peter,S.,1/22/2015,8:30AM,5:30PM,PURCHASING

    here are my ff file names:

    WRAPPER.KSH ./EXPORT_AMS.KSH -MOVE FROM SOURCE TO OPS FOLDER ./TRANSFORM_AMS_PPS.KSH - transform AMS format to PPS ./IMPORT_PPS.KSH - MOVE FROM OPS TO DEST WRAPPER TRANSFORM AMS.CSV TO PPS.CSV AMS ---> PPS
Substitution backreference woes
5 direct replies — Read more / Contribute
by Anonymous Monk
on Jan 24, 2015 at 07:43

    I'm trying to work out how Perl substitutions work. We're told that backreference patterns can be used in the substitution by specifying \1, \2 (etc), but it doesn't seem to work.

    Snippet below. It tries to turn the string 'Hello sailor' into 'Goodbye sailor', but I get 'Goodbye \1' instead.

    (Obviously this isn't sensible way to convert one string to the other, but this is just an example.)

    #!/usr/bin/perl use strict; use diagnostics; use warnings; my $string = 'Hello sailor'; my $regex = 'Hello (.*)'; my $substitution = 'Goodbye \1'; $string =~ s/$regex/$substitution/; print "string is now $string \n"; # I wanted: string is now Good bye sailor # I got: string is now Good bye \1
Break sentence into two part
6 direct replies — Read more / Contribute
by Mjpaddy
on Jan 24, 2015 at 01:36

    Hello monks, Is there is any module or method which can make a sentence into two equal part or half or partially half

    Suppose this is a sentence as follow:

    Perl 5 is a highly capable, feature-rich programming language with over 27 years of development.

    which method will be used in order to get result like:

    $firsthalf: Perl 5 is a highly capable, feature-rich programming

    $sechalf : language with over 27 years of development.

    Thanks in advanced

Whenever perl meets namedpipe it gets blocked
3 direct replies — Read more / Contribute
by Anonymous Monk
on Jan 23, 2015 at 13:29

    I wrote a simple that prints only files recursively. But I have a problem.
    whenever It meets named pipe, it gets blocked at all!
    I thought it would be ok if I add just -p test,but that's too late because program is blocked when opening the named pipe!

    #!/usr/bin/perl -w use latest; use File::Spec; my $test=$ARGV[0]; my $ds='/'; sub bfs { my $path=$_[0]; push(my @queue,$path); my ($current,@output); while(@queue) { $path=shift(@queue); if($path=~/${ds}\.{1,2}$/){next} opendir($current,$path) or open($current,$path) or next; if(-d $current) { push @queue,map {File::Spec->catfile($path,$_)} readdir $c +urrent; closedir $current } elsif(-f $current) { say $path; close $current; push @output,$path; } } @output; } bfs($test);
Replicate a website GUI functionality
1 direct reply — Read more / Contribute
by doubledecker
on Jan 23, 2015 at 13:10

    Hi Monks

    I want to implement / replicate the functionality of the following website.

    https://xkpasswd.net/s/

    The core functionality is written using Perl. However, I am interested in replicating the GUI of this website. Any thoughts on how to implement and technologies involved.

caching formats
5 direct replies — Read more / Contribute
by hotpelmen
on Jan 22, 2015 at 13:31
    Hi,

    Background: there's a script that generates a standard-width text report by writing report into a file line by line. For most lines in the report it uses common format, but for some lines, based on some unpredictable runtime information, it needs to dynamically define a custom format. These custom formats have unpredictable "pictures", so it is impossible to pre-define all such formats in advance. Dynamic generation of custom formats is done via eval (as described in perlform). Since some lines end up using the same exact custom format, it would be beneficial to try to reuse it instead of generating and eval-ing the same string again and again.

    Question: Other than maintaining a separate hash with created format names, what's the best & cheapest method of format caching here, i.e. determining if a format with a given name is already defined and available for assignment to the filehandle? I read that formats use their own namespace but I could not find any information on how to access it. Any help with this specific question would be greatly appreciated.

Moose: Problems subtyping a coerced subtype
1 direct reply — Read more / Contribute
by BaldManTom
on Jan 21, 2015 at 12:27

    Using Moose, I've got a subtype 'AFile' which coerces a String to a Path::Class::File. I'm trying to create a subtype of 'AFile' called 'ExistingFile' where I'm trying to verify that the file exists. When I create an object that has an attribute of type 'ExistingFile', if I pass in a Path::Class::File, everything "seems" to work, but if I pass in a String, things fail. It appears that in the event the attribute is being coerced, the "where" clause in the 'ExistingFile' subtype is being skipped. Here's some code to illustrate what I'm seeing:

    #! /usr/bin/env perl use strict; use warnings; use 5.10.0; package Foo; use Moose; use Moose::Util::TypeConstraints; use namespace::autoclean; use Path::Class qw / file /; subtype 'AFile' => as 'Path::Class::File' => message { 'Item is not a Path::Class::File' }; coerce 'AFile' => from 'Str' => via { file($_) }; subtype 'ExistingFile' => as 'AFile' => where { say "In subtype where clause: $_[0]"; -f $_[0] }, message { "$_[0] does not exist" }; has file => ( isa => 'ExistingFile', is => 'ro', required => 1 ); __PACKAGE__->meta->make_immutable; package main; use Path::Class qw / file /; say $0; eval { my $foo = Foo->new(file => file($0)); }; say ":::".$@.":::"; eval { my $foo = Foo->new(file => $0); }; say ":::".$@.":::";

    And the output when I run the above:

    subtype_madness.pl In subtype where clause: subtype_madness.pl :::::: :::Attribute (file) does not pass the type constraint because: subtype +_madness.pl does not exist at constructor Foo::new (defined at subtyp +e_madness.pl line 29) line 34 Foo::new('Foo', 'file', 'subtype_madness.pl') called at subtype_ma +dness.pl line 36 eval {...} at subtype_madness.pl line 36 :::

    While this example has all the code in one place, in my "real world" the 'AFile' subtype is off in a library somewhere.

    I could work around this by creating 'ExistingFile' as a subtype of Path::Class::File, but it *seems* like I should be able to subtype 'AFile'. Thoughts?

Help with Unix::Mgt on BSD
2 direct replies — Read more / Contribute
by mikosullivan
on Jan 21, 2015 at 11:53

    Disclaimer: I hope it's cool posting this request here. It seemed the most appropriate monk spot. Please let me know if there's a better place for this request.

    I'm currently developing the module Unix::Mgt. The purpose of this module is to provide Uni*x management tools that directly call the system's tool for those purposes, as opposed to directly editing /etc/passwd or /etc/group.

    The problem is that I don't have access to a BSD system, so I can't write the appropriate code for management on BSD.

    Would somebody like to help write those sections of the module what would work on BSD? It shouldn't be too difficult, just putting some values into an array. My code already does the work of making the system calls. Please see Help with BSD development for details.

    Thanks and happy coding. - Miko

IO::Socket::SSL is not downloading full data from HTTPS URL in Windows ActiveState Perl.
3 direct replies — Read more / Contribute
by sam_bakki
on Jan 21, 2015 at 06:10

    Dear Monks,

    While downloading data from HTTPS URL, I see different results in Net::SLL and IO::Socket::SSL. Basically, IO::Socket::SSL is not downloading full data.

    To show whats really happening, I have two scripts below,

    One uses the Net::SSL and downloads data properly from Server
    Other uses IO::Socket::SSL and downloads only first chunk (I think) from server and quits.

    To show the differences b/w downloads, I have shown MD5 sum and file sizes.

    My environment
    OS: Windows 7 , x86_64 bit Perl: Active Perl , perl 5, version 20, subversion 1 (v5.20.1) built for MSWin32-x86-multi-thread-64int

    Note: I saw the same behavior in Active Perl 5.10, 5.14, 5.16 and 5.18

    Script 1 - Using Net::SSL and Crypt::SSLeay - Working

    #WORKING HTTPS DOWNLOAD Using Net::SSL in Windows + Active Perl use strict; use warnings; use Crypt::SSLeay; use Net::SSL; use WWW::Mechanize; use HTTP::Cookies; use HTTP::Message; use Digest::MD5; use File::Slurp; use Data::Dumper; use Devel::ModuleDumper; #Globals $|=1; #Force LWP to use Net::SSL instead of IO::Socket::SSL $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL"; $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; delete $ENV{https_proxy} if exists $ENV{https_proxy}; delete $ENV{http_proxy} if exists $ENV{http_proxy}; #Variables my $browser = ""; my $url = 'https://developer.apple.com/standards/qtff-2001.pdf'; my $pageContent = ''; my $fileName = ''; my $md5Obj = Digest::MD5->new(); print "\n USING Net::SSL"; #Init Mechanize $browser = WWW::Mechanize->new(autocheck =>1, noproxy=>1, ssl_opts => +{ 'verify_hostname' => 0 }); # Add cookie jar $browser->cookie_jar(HTTP::Cookies->new()); $browser->agent_alias( 'Linux Mozilla'); $browser->add_header('Accept-Encoding'=>scalar HTTP::Message::decodabl +e()); $browser->timeout(120); #Get URL $browser->get($url); if ($browser->success()) { print "\n INFO: Got URL: $url"; $fileName = $browser->response()->filename(); print "\n INFO: Save in File: $fileName"; $browser->save_content($fileName); #Calculate MD5 sum $pageContent = read_file( $fileName, binmode => ':raw' ); print "\n INFO: $fileName Size: ", length($pageContent)/1024," KB" +; $md5Obj->add($pageContent); print "\n INFO: $fileName MD5 Sum: ", $md5Obj->hexdigest(); undef $md5Obj; } else { print "\n ERROR: Can't get URL $url ",$browser->status(); } print "\n\n INFO: ********************* DUMP ********************"; print "\n",Dumper(\$browser); print "\n INFO: ********************* DUMP ********************"; exit 0;

    Output1:

    
      USING Net::SSL
     INFO: Got URL: https://developer.apple.com/standards/qtff-2001.pdf
     INFO: Save in File: qtff-2001.pdf
     INFO: qtff-2001.pdf Size: 5465.48046875 KB
     INFO: qtff-2001.pdf MD5 Sum: d1aee95cc06d529e67b707257a5cf3eb
    
    Loaded Modules
    -------------------
    Carp	1.3301
    Compress::Raw::Bzip2	2.068
    Compress::Raw::Zlib	2.068
    Compress::Zlib	2.068
    Crypt::SSLeay	0.72
    Crypt::SSLeay::CTX	none
    Crypt::SSLeay::MainContext	none
    Crypt::SSLeay::X509	none
    Data::Dumper	2.154
    Digest::base	1.16
    Digest::MD5	2.53
    Encode	2.67
    Encode::Alias	2.18
    Encode::Config	2.05
    Encode::Encoding	2.07
    Errno	1.2003
    Exporter	5.70
    Exporter::Heavy	5.70
    Fcntl	1.11
    File::Glob	1.23
    File::GlobMapper	1.000
    File::Slurp	9999.19
    HTML::Entities	3.69
    HTML::Form	6.03
    HTML::Parser	3.71
    HTML::PullParser	3.57
    HTML::Tagset	3.20
    HTML::TokeParser	3.69
    HTTP::Config	6.00
    HTTP::Cookies	6.01
    HTTP::Cookies::Netscape	6.00
    HTTP::Date	6.02
    HTTP::Headers	6.05
    HTTP::Headers::Util	6.03
    HTTP::Message	6.06
    HTTP::Request	6.00
    HTTP::Request::Common	6.04
    HTTP::Response	6.04
    HTTP::Status	6.03
    IO	1.31
    IO::Compress::Adapter::Deflate	2.068
    IO::Compress::Base	2.068
    IO::Compress::Base::Common	2.068
    IO::Compress::Gzip	2.068
    IO::Compress::Gzip::Constants	2.068
    IO::Compress::RawDeflate	2.068
    IO::Compress::Zlib::Constants	2.068
    IO::Compress::Zlib::Extra	2.068
    IO::File	1.16
    IO::Handle	1.35
    IO::Seekable	1.1
    IO::Socket	1.37
    IO::Socket::INET	1.35
    IO::Socket::IP	0.35
    IO::Socket::UNIX	1.26
    IO::Uncompress::Adapter::Bunzip2	2.068
    IO::Uncompress::Adapter::Inflate	2.068
    IO::Uncompress::Base	2.068
    IO::Uncompress::Bunzip2	2.068
    IO::Uncompress::Gunzip	2.068
    IO::Uncompress::Inflate	2.068
    IO::Uncompress::RawInflate	2.068
    List::Util	1.41
    LWP	6.08
    LWP::MemberMixin	none
    LWP::Protocol	6.06
    LWP::Protocol::http	none
    LWP::Protocol::https	6.06
    LWP::UserAgent	6.06
    MIME::Base64	3.14
    Net::HTTP	6.07
    Net::HTTP::Methods	6.07
    Net::HTTPS	6.04
    Net::SSL	2.86
    POSIX	1.38_03
    Scalar::Util	1.41
    SelectSaver	1.02
    Socket	2.016
    Storable	2.51
    Symbol	1.07
    Tie::Hash	1.05
    Time::Local	1.2300
    URI	1.65
    URI::Escape	3.31
    URI::http	none
    URI::https	none
    URI::_generic	none
    URI::_query	none
    URI::_server	none
    WWW::Mechanize	1.73
    
    

    Script 2 - Using IO::Socket::SSL - Not Working. Only part of the PDF file is downloaded

    #NOT WORKING HTTPS DOWNLOAD Using IO::Socket::SSL in Windows + Active +Perl use strict; use warnings; use IO::Socket::SSL; use WWW::Mechanize; use HTTP::Cookies; use HTTP::Message; use Digest::MD5; use File::Slurp; use Data::Dumper; use Devel::ModuleDumper; #Globals $|=1; $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0; #Variables my $browser = ""; my $url = 'https://developer.apple.com/standards/qtff-2001.pdf'; my $pageContent = ''; my $fileName = ''; my $md5Obj = Digest::MD5->new(); print "\n USING IO::Socket::SSL"; #Init Mechanize $browser = WWW::Mechanize->new(autocheck =>1, noproxy=>1,ssl_opts => { + 'verify_hostname' => 0 }); # Add cookie jar $browser->cookie_jar(HTTP::Cookies->new()); $browser->agent_alias( 'Linux Mozilla'); $browser->add_header('Accept-Encoding'=>scalar HTTP::Message::decodabl +e()); $browser->timeout(120); #Get URL $browser->get($url); if ($browser->success()) { print "\n INFO: Got URL: $url"; $fileName = $browser->response()->filename(); print "\n INFO: Save in File: $fileName"; $browser->save_content($fileName); #Calculate MD5 sum $pageContent = read_file( $fileName, binmode => ':raw' ); print "\n INFO: $fileName Size: ", length($pageContent)/1024," KB" +; $md5Obj->add($pageContent); print "\n INFO: $fileName MD5 Sum: ", $md5Obj->hexdigest(); undef $md5Obj; } else { print "\n ERROR: Can't get URL $url ",$browser->status(); } print "\n\n INFO: ********************* DUMP ********************"; print "\n",Dumper(\$browser); print "\n INFO: ********************* DUMP ********************"; exit 0;

    Output2:

    
      USING IO::Socket::SSL
     INFO: Got URL: https://developer.apple.com/standards/qtff-2001.pdf
     INFO: Save in File: qtff-2001.pdf
     INFO: qtff-2001.pdf Size: 6.66796875 KB
     INFO: qtff-2001.pdf MD5 Sum: 4049c364f7332790c3abe548d6a4297c
    
    Loaded Modules
    ----------------
    ActivePerl::Config      none
    Carp    1.3301
    Compress::Raw::Bzip2    2.068
    Compress::Raw::Zlib     2.068
    Compress::Zlib  2.068
    Cwd     3.48
    Data::Dumper    2.154
    Digest::base    1.16
    Digest::MD5     2.53
    Encode  2.67
    Encode::Alias   2.18
    Encode::Byte    2.04
    Encode::Config  2.05
    Encode::Encoding        2.07
    Encode::Locale  1.03
    Errno   1.2003
    Exporter        5.70
    Exporter::Heavy 5.70
    Fcntl   1.11
    File::Basename  2.85
    File::Glob      1.23
    File::GlobMapper        1.000
    File::Slurp     9999.19
    File::Spec      3.48
    File::Spec::Unix        3.48
    File::Spec::Win32       3.48
    HTML::Entities  3.69
    HTML::Form      6.03
    HTML::Parser    3.71
    HTML::PullParser        3.57
    HTML::Tagset    3.20
    HTML::TokeParser        3.69
    HTTP::Config    6.00
    HTTP::Cookies   6.01
    HTTP::Cookies::Netscape 6.00
    HTTP::Date      6.02
    HTTP::Headers   6.05
    HTTP::Headers::Util     6.03
    HTTP::Message   6.06
    HTTP::Request   6.00
    HTTP::Request::Common   6.04
    HTTP::Response  6.04
    HTTP::Status    6.03
    IO      1.31
    IO::Compress::Adapter::Deflate  2.068
    IO::Compress::Base      2.068
    IO::Compress::Base::Common      2.068
    IO::Compress::Gzip      2.068
    IO::Compress::Gzip::Constants   2.068
    IO::Compress::RawDeflate        2.068
    IO::Compress::Zlib::Constants   2.068
    IO::Compress::Zlib::Extra       2.068
    IO::File        1.16
    IO::Handle      1.35
    IO::Seekable    1.1
    IO::Socket      1.37
    IO::Socket::INET        1.35
    IO::Socket::IP  0.35
    IO::Socket::SSL 2.010
    IO::Socket::SSL::PublicSuffix   none
    IO::Socket::UNIX        1.26
    IO::Uncompress::Adapter::Bunzip2        2.068
    IO::Uncompress::Adapter::Inflate        2.068
    IO::Uncompress::Base    2.068
    IO::Uncompress::Bunzip2 2.068
    IO::Uncompress::Gunzip  2.068
    IO::Uncompress::Inflate 2.068
    IO::Uncompress::RawInflate      2.068
    List::Util      1.41
    LWP     6.08
    LWP::MemberMixin        none
    LWP::Protocol   6.06
    LWP::Protocol::http     none
    LWP::Protocol::https    6.06
    LWP::UserAgent  6.06
    Mozilla::CA     20141217
    Net::HTTP       6.07
    Net::HTTP::Methods      6.07
    Net::HTTPS      6.04
    Net::SSLeay     1.66
    POSIX   1.38_03
    Scalar::Util    1.41
    SelectSaver     1.02
    Socket  2.016
    Socket6 0.25
    Storable        2.51
    Symbol  1.07
    Tie::Hash       1.05
    Time::Local     1.2300
    URI     1.65
    URI::Escape     3.31
    URI::http       none
    URI::https      none
    URI::_generic   none
    URI::_idna      none
    URI::_punycode  1.65
    URI::_query     none
    URI::_server    none
    Win32::API      0.79
    Win32::API::Struct      0.65
    Win32::API::Type        0.69
    Win32::Console  0.10
    WWW::Mechanize  1.73
    
    

    I did not paste the Dumper output because its huge and not properly copied to browser because of the binary contents.

    Q: Why IO::Socket::SSL is not downloading full data? What more should I need to do in Script 2.

    Update: Added Module versions

    Update1: I have tested the Script2 in Linux Fedora 21, x64, Perl 5.18, It's is working fine :). So this looks like only problem in Windows + ActiveState Perl :(

    Thanks & Regards,
    Bakkiaraj M
    My Perl Gtk2 technology demo project - http://code.google.com/p/saaral-soft-search-spider/ , contributions are welcome.

New Meditations
RFC: automating modular classes
No replies — Read more | Post response
by Arunbear
on Jan 26, 2015 at 08:44

    Minions is yet another OOP automation module, roughly similar to Moo, but which has the addtional goal of putting Encapsulation centre stage. I wrote it because after reading How Large Does Your Project Have To Be to Justify Using Moose? (especially the comments by tye and JavaFan), I became increasingly disillusioned with the Moo(se) way of OOP (essentially OOP with no Encapsulation).

    Here is a sample that implements the fixed size queue from Re^5: The future of Perl? (that sub-thread also illustrates limitations of the Moo way of OOP)
    package FixedSizeQueue; use Minions interface => [qw( push pop size )], construct_with => { max_items => { assert => { positive_int => sub { $_[0] =~ /^\d+$/ && $_[0 +] > 0 } }, }, }, implementation => 'FixedSizeQueue::Default', ; 1; package FixedSizeQueue::Default; use Minions::Implementation has => { q => { default => sub { [ ] } }, max_size => { init_arg => 'max_items', }, }, ; sub size { my ($self) = @_; scalar @{ $self->{$__q} }; } sub push { my ($self, $val) = @_; log_info($self); push @{ $self->{$__q} }, $val; if ($self->size > $self->{$__max_size}) { $self->pop; } } sub pop { my ($self) = @_; log_info($self); shift @{ $self->{$__q} }; } sub log_info { my ($self) = @_; warn sprintf "[%s] I have %d element(s)\n", scalar(localtime), $se +lf->size; } 1;
    And a sample of usage:
    % reply -I lib 0> use FixedSizeQueue 1> my $q = FixedSizeQueue->new(max_items => 3) $res[0] = bless( { '932db126-' => 'FixedSizeQueue::__Private', '932db126-max_size' => 3, '932db126-q' => [] }, 'FixedSizeQueue::__Minions' ) 2> $q->can $res[1] = [ 'pop', 'push', 'size' ] 3> $q->push($_) for 1 .. 3 [Mon Jan 26 12:01:53 2015] I have 0 element(s) [Mon Jan 26 12:01:53 2015] I have 1 element(s) [Mon Jan 26 12:01:53 2015] I have 2 element(s) $res[2] = '' 4> $q->pop [Mon Jan 26 12:02:09 2015] I have 3 element(s) $res[3] = 1 5> $q $res[4] = bless( { '932db126-' => 'FixedSizeQueue::__Private', '932db126-max_size' => 3, '932db126-q' => [ 2, 3 ] }, 'FixedSizeQueue::__Minions' ) 6> $q->push($_) for 4 .. 6 [Mon Jan 26 12:02:55 2015] I have 2 element(s) [Mon Jan 26 12:02:55 2015] I have 3 element(s) [Mon Jan 26 12:02:55 2015] I have 4 element(s) [Mon Jan 26 12:02:55 2015] I have 3 element(s) [Mon Jan 26 12:02:55 2015] I have 4 element(s) $res[5] = '' 7> $q $res[6] = bless( { '932db126-' => 'FixedSizeQueue::__Private', '932db126-max_size' => 3, '932db126-q' => [ 4, 5, 6 ] }, 'FixedSizeQueue::__Minions' ) 8> $q->log_info() Can't locate object method "log_info" via package "FixedSizeQueue::__M +inions" at reply input line 1. 9>
    Not all Moo features are supported (for this early release I've focused on those I actually use). Important differences from Moo include
    1. Attributes can be safely accessed inside classes without the overhead of a function call
    2. As a consequence of 1., attributes need not be exposed via methods (unless there is a good reason to do so).
    3. No need to clean up animal droppings
    4. Private subroutines via the mechanism shown in Re: OO - best way to have protected methods (packages)
    5. Class methods are "class only", and object methods are "object only"
    6. No compatibility with Moose
    Feedback is much appreciated.
The Boy Scout Rule
8 direct replies — Read more / Contribute
by eyepopslikeamosquito
on Jan 25, 2015 at 04:59

    You've got your typical company started by ex-software salesmen, where everything is Sales Sales Sales and we all exist to drive more sales.

    On the other extreme you have typical software companies built by ex-programmers. These companies are harder to find because in most circumstances they keep quietly to themselves, polishing code in a garret somewhere, which nobody ever finds, and so they fade quietly into oblivion right after the Great Ruby Rewrite, their earth-changing refactoring-code code somehow unappreciated by The People.

    -- The Developer Abstraction Layer by Joel Spolsky

    Though my natural inclination is to be a bit OCD about keeping code clean, I concede that spending too much time and money on refactoring, writing programmer tools, and endlessly polishing code will likely lead to commercial failure. As will the converse, namely neglecting your developers and their code and architectures in favour of sales and marketing. Successful software companies tend to have a healthy balance.

    Refactoring

    Booking.com, perhaps the most commercially successful Perl-based company, has caused a bit of controversy over the years with their attitude towards refactoring. To give you a flavour, I present a couple of comments below:

    Booking is destroying my career because I am not allowed to do anything new. I am not allowed to use new technologies. I'm not allowed to "design" anything big. I am not allowed to write tests. I am allowed to copy that 500 line subroutine into another module. If people have done that several times before, maybe it should be refactored instead of duplicated? If you do that, you get in trouble. As one boss says, "we do not pay you to write nice code. We pay you to get job done."

    Management, and the term is quite lose when applied to Booking.com, sees no gain in refactoring code. By refactoring I'm talking about taking a few weeks to rewrite an existing piece of software. By definition refactoring doesn't bring new functionality so this is why management is reluctant to go down that road. We're quite lenient about code that gets added to the repo, as long as there's a business reason behind it. If a quick hack can be deployed live and increase conversion then it will be accepted. But rest assured that crappy code doesn't last long, specially if other devs have to use it or maintain it.

    -- from Truth about Booking.com (Blog)

    One of the posts specifically deals with the culture of "get it done and fast" and how they do not encourage refactoring or basic testing. I actually work in a Perl shop where management has the same kind of mentality, and it is slowly killing our efficiency.

    Regarding testing, it's true that we're not very unit testing focused. This is mainly because we've decided to spend most of the time/money/infrastructure that you might usually spend on unit testing on monitoring instead. If you have unit tests you still need monitoring, but in practice if your monitoring is good enough and you have an infrastructure to quickly rollout & rollback systems you can replace much of unit testing with monitoring.

    We're not adverse to refactoring when appropriate. But if you're going to propose rewriting some code here you'll actually have to make a compelling case for it which isn't just "the old code is hairy". Do you actually understand what it does? Maybe it's hairy and complex because it's solving a hairy and complex problem. Are you not aware of where this system fits into the big picture? We've also had code that's looks fantastic, had tests, used lots of best practices that we've had to throw away completely because it was implementing some idea that turned out to be plain stupid.

    -- from What exactly is up with Booking.com? (reddit)

    Opportunistic Refactoring and The Boy Scout Rule

    Some people object to such refactoring as taking time away from working on a valuable feature. But the whole point of refactoring is that it makes the code base easier to work with, thus allowing the team to add value more quickly. If you don't spend time on taking your opportunities to refactor, then the code base gradually degrades and you're faced with slower progress and difficult conversations with sponsors about refactoring iterations.

    There is a genuine danger of going down a rabbit hole here, as you fix one thing you spot another, and another, and before long you're deep in yak hair. Skillful opportunistic refactoring requires good judgement, where you decide when to call it a day. You want to leave the code better than you found it, but it can also wait for another visit to make it the way you'd really like to see it. If you always make things a little better, then repeated applications will make a big impact that's focused on the areas that are frequently visited - which are exactly the areas where clean code is most valuable.

    -- Opportunistic Refactoring (Martin Fowler)

    The Boy Scouts have a rule: "Always leave the campground cleaner than you found it"

    What if we followed a similar rule in our code: "Always check a module in cleaner than when you checked it out"

    -- The Boy Scout Rule (O'Reilly)

    At work, we perform opportunistic refactoring following the Boy Scout rule, trusting the judgement of developers. How do you do it at your workplace?

    Code Reviews

    By way of background, my company went agile about five years ago, at first with great zealotry, nowadays with more maturity and less dogma.

    Before check-in, all code must be reviewed, either continuously via pair programming, or via a lightweight code review (typically over-the-shoulder). We also have a coding standard, though it is not strongly enforced.

    To give a concrete example, during a code review the other day, I persuaded the author to eliminate unnecessary repetition by changing this snippet:

    my $config = <<'GROK'; ADD UDP_LISTENER ( 515 ) ADD UDP_LISTENER ( 616, 657 ) ADD UDP_LISTENER ( 987 ) GROK my @test_cases = ( { desc => "# Test 1", conf => $config, find => [ 'port = 515', 'port = 616', 'port = 657', 'port = 987' + ], }, );
    to:
    my $liststr = 'ADD UDP_LISTENER'; my @ports = ( 515, 616, 657, 987 ); my $config = <<"GROK"; $liststr ( $ports[0] ) $liststr ( $ports[1], $ports[2] ) $liststr ( $ports[3] ) GROK my @test_cases = ( { desc => "# Test 1", conf => $config, find => [ map { "port = $_" } @ports ], }, );

    What would you have done?

    I'm sure some other programmers at my company wouldn't have bothered suggesting any changes at all: after all, the code worked as is, it's pretty clear, plus "it's only a test script", so why bother?

    Though I felt the code was more maintainable with duplication eliminated, I had another motivation in this specific case: training. You see, the programmer in question was very new to Perl and, as I found out during the review, had never used map before! Training (and improved teamwork) are important benefits of code reviews.

    Eliminating unnecessary duplication and repetition is a common discussion topic during code review in my experience. (Note: I did not include this example to argue further about what DRY means exactly in Room 12A :). Other common discussion points during code review are:

    • Commenting.
    • Naming.
    • Clarity vs Cleverness.
    • Encapsulation.
    • Interfaces.
    • Error handling.
    • Testability. Is the code testable in isolation?
    • Supportability.
    • Portability.
    • Security.
    • Performance.
    Note that we do not normally discuss code layout because all code is pushed through Perl::Tidy before review.

    I'm interested to learn about your workplace experiences. In particular:

    • Do you have a coding standard? How is it enforced?
    • Do you do pair programming?
    • Do you do code reviews? Are they heavyweight (e.g. Fagan Inspection) or lightweight (e.g. over-the-shoulder)? Mandatory or optional?
    • What are common discussion points during your code reviews?

    Cleverness

    To finish, here's another one, derived from Clever vs. Readable.

    Would this statement pass your code review?

    my $value = [ $x => $y ] -> [ $y <= $x ];
    If not, would you suggest changing it to:
    my $value = $x < $y ? $x : $y;
    or:
    use List::Util qw(min); my $value = min( $x, $y );
    Or something else?

    References

Empty string but True
1 direct reply — Read more / Contribute
by Yary
on Jan 22, 2015 at 11:30
    I was looking at an old StackOverflow question about generating an explicit null XML namespace and had the thought, "maybe an object that stringifies to the empty string, but is true in every other context, will trick LibXML into doing what the seeker of wisdom required."

    It did not, nor did an earlier attempt using than Scalar::Util's dualvar. Still I liked my little Empty but True module enough to post it here. (Seems too useless/dangerous/not worth the bother to be on CPAN.)

    package MyEmptyTrueVar; our $singleton; use overload fallback => 'TRUE', '""' => sub { "" }, # Return empty string on stringification bool => sub { 1 }, # Return true in boolean context '0+' => sub { 1 }, # Return true in numeric context cmp => sub { !ref $_[1] }; # unequal to empty string, or any other +string bless $singleton=\$singleton;
    usage:
    say "Single str='$MyEmptyTrueVar::singleton', Num=", (0+$MyEmptyTrueVa +r::singleton) if $MyEmptyTrueVar::singleton && $MyEmptyTrueVar::singleton ne '' && '' ne $MyEmptyTrueVar::singleton;
    shows that Single str='', Num=1.
New Monk Discussion
"Please, log in ..."
7 direct replies — Read more / Contribute
by sundialsvc4
on Jan 20, 2015 at 12:45

    Lately, I am seeing a lot of technical comments ... and even entire threads ... which are being made by Anonymous Monk.   These are not particularly negative comments.   These are not people dodging (or firing ...) the downvote-bullet to protect their precious-to-them reputations.   No, nothing “snarky” at all.   They are technical comments, and good ones, therefore by-the-way quite worthy of upvotes.   In one case today, Anonymous is heard saying, “if you remember my previous post [on the subject].”   Problem:   how easy is it going to be to find that particular post, and, having found it, to know that it’s the one referred to?   Now fast-forward six months ... a year ... the post is long forgot, but an intrepid soul with a problem is doing a Super Search.   Can he find your exact comment, quickly, now?

    Oops, you see that you made an error.   Can you go back and fix it now?   Nope!   Not good:   now, and forevermore, the PM database contains an error, or at least, unfinished business.   The post belongs to no-one now.   From an information-quality standpoint, that’s not good.

    I think that we should strongly encourage people to log in when they post comments.   (I have said, before, that I actually don’t like the idea of Anonymous at all ...)   But here’s the main reason for my suggestion:   if I know who you are, I can search for you.   I can find your other posts, probably without trolling through dozens of pages.   I can use your name as part of the Super Search criteria.   All of which cannot be so-effectively done in the case of our Anonymous brother.

    We always need to keep in mind, not just the present, but the future.   More than its dubious value as a social gathering-place for geeks, PM is very much an information resource of very durable, long-lasting value.   People do look for information that is months or years old, and find it just as valuable as when it was written, if they can find it and identify it.   Therefore, sign your name to your posts.   It really isn’t a petty-game of pluses and minuses ... rather, it is something that I think adds real value to your posts when you include it; and removes much of that value when you don’t.

    Another, related suggestion would be to emphasize the value of weaving searchable keywords into post responses, especially if the original thread or its title did not include relevant terms.   And, to be sure that posts represent complete thoughts, to include not only our suggestions but the context/assumptions in which they are made.   Searches consider individual posts, not merely threads.   The searcher will encounter the post before s/he encounters its thread context.   Therefore, make every post count.   Once again, we are pandering to our intrepid Super Searcher from the Future, and in so doing, helping PM to continue to be:   “the Go-To Site on the Internet™” for questions regarding Perl and technical computing.

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: (13)
As of 2015-01-26 19:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My top resolution in 2015 is:

















    Results (196 votes), past polls