Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

reference , advantages?

by dbs (Sexton)
on Jun 30, 2011 at 17:33 UTC ( #912216=perlquestion: print w/replies, xml ) Need Help??

dbs has asked for the wisdom of the Perl Monks concerning the following question:

Looking at some of my older scripts I had written. What is the advantage of this reference use or in general why are reference useful compared to scalars? I have only used them 1-2 times that I can remember.
use strict; use warnings; >snip< sub new_date { my ( $year, $month, $day ) = (localtime)[ 5, 4, 3 ]; sprintf( "%04d%02d%02d", ( $year += 1900 ), $month + 1, $day ); } $passed_new_date = new_date(); sub new_date_append { return $monster_date = "OhioS$passed_new_date"; } $fref = \&new_date_append(); ###--- HERE is my REF ---### >snip< if ( $passed_new_date and $$fref ) { calls 2 subs.... }
thx! HERE IS THE WHOLE KITnKABOODLE I wrote it back in 2004...to be kind.
use strict; use warnings; use Net::FTP; use MIME::Lite; my ( $ftplog, $fref ); my $OHMONSTER; my $RENAMED = q/OhioS.xml/; my ( $monster_date, $passed_new_date ) = 0; my $overide = $SIG{__DIE__}; ## get error handler currently assigne +d to die() $SIG{__DIE__} = sub { my $error = shift; ## error now holds the mesg passed to +die $overide->($error) if ( ref $overide ); mailme($error); }; sub new_date { my ( $year, $month, $day ) = (localtime)[ 5, 4, 3 ]; sprintf( "%04d%02d%02d", ( $year += 1900 ), $month + 1, $day ); } $passed_new_date = new_date(); sub new_date_append { return $monster_date = "OhioS$passed_new_date"; } $fref = \&new_date_append(); sub mailme { my $error = shift; my $msg = MIME::Lite->new( From => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx>', To => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx>', To => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx>', Subject => "HRIS FTP Inbound to monster.com had problems and or failed:\t\t$e +rror", Type => 'multipart/related' ); $msg->attach( Type => 'TEXT', Disposition => 'attachment', Path => "$ftplog", Filename => "$ftplog" ); $msg->send; } ## Delete files older than 12 days sub filetest { my $e = 0; my @diraray = glob("/psofthr/hr88prd/intf/monster/inbound/*"); foreach $e (@diraray) { if ( -M $e > 12 ) { unlink $e; } } } sub ftpme { my $remotehost = "ftp.monster.com"; my $remotedir = "xxxxxxx"; my $localdir = "/psofthr/hr88prd/intf/monster/inbound"; my $user = "xxxx"; my $pass = "xxxx"; $ftplog = "/psofthr/hr88prd/intf/monster/log/interface_monster.log"; open( FTPLOG, ">>$ftplog" ) || warn "Could not open FTPLOG FH $!"; my $ftp = Net::FTP->new( $remotehost, Debug => 10 ) || die "Failed to connect to $remotehost: $!", print FTPLOG "\n$passed_new_date\nFailed to connect to $remotehost! +"; print FTPLOG $passed_new_date; $ftp->login( $user, $pass ) || die "Login failed at $remotehost!: $!" +, print FTPLOG "\n$passed_new_date\nLogin Failed at $remotehost!"; $ftp->binary(); $ftp->cwd($remotedir) || die "CWD to folder outbound failed!: $!", print FTPLOG "\n$passed_new_date\nCWD to folder outbound failed!"; foreach ( $ftp->ls() ) { if (/${$fref}\d+\w+/) { $OHMONSTER = $_; $ftp->get( $OHMONSTER, "$localdir/$OHMONSTER" ) || die "FTP get from monster.com failed!: $!", print FTPLOG "\nFTP get at monster.com failed!"; sleep 2; $ftp->delete($RENAMED) || die "FTP dele of existing file at monster.com failed! : $!", print FTPLOG "\nFTP dele at monster.com failed!"; sleep 2; $ftp->rename( "$OHMONSTER", "$RENAMED" ) || die "FTP rename at monster.com failed!: $!", print FTPLOG "\n$passed_new_date\nFTP rename at monster.com faile +d!"; print FTPLOG $passed_new_date; last; } } $ftp->quit; close(FTPLOG) || warn "was unable to close FTPLOG FH $!"; } if ( $passed_new_date and $$fref ) { ftpme(); filetest(); } else { my $error = 'variables for FTP rename at monster.com were not set, rename will not + work & process will fail!'; mailme($error); }

Replies are listed 'Best First'.
Re: reference , advantages?
by davido (Cardinal) on Jun 30, 2011 at 18:21 UTC

    Ignoring the code you posted, aside from taking note of its indication that you might be asking specifically about sub references.....

    Why sub references may be useful is really up to the imagination of the programmer, just as why while() {} may be useful. Sub refs are tools for you to put in your tool chest and use as they are found to be useful. In the type of work you do, you may find them to be seldom used. Others may find them extremely useful. A carpenter doesn't often use an oil filter wrench. A mechanic doesn't often use a nail gun. But farmer may use both in the course of his work-month.

    If the hats you wear ever include using CGI::Carp, you might be exposed to using a sub-reference to set up your own error-handler. If you ever use File::Find, you use a subref for the "found" callback. If you program user interfaces, or parsers, you'll often use subrefs for event handlers and token handlers. Sub references allow a general solution to be applied to a specific situation.

    References in general are a form of abstraction. An array, a hash, a subroutine, a simple scalar holding a value... they're abstraction layers that are very close to the data. When we need to apply a more generalized solution, we use references to those layers to distance ourselves from the data itself.

    David Wheeler has been quoted as saying, "Any problem in computer science can be solved with another layer of indirection." References are one form of indirection. Of course the same Wheeler went on to qualify that with, "....Except for the problem of too many layers of indirection. (Thanks Wikipedia, for the quotes.)


    Dave

Re: reference , advantages?
by luis.roca (Deacon) on Jun 30, 2011 at 17:51 UTC
    Hello dbs,

    In general references are useful for creating nested data structures such as an Array of Arrays, Hash of Arrays, Array of Hashes etc. Check out perldsc for lots of examples and further explanation. The first several chapters of Mastering Algorithms with Perl also provide good recipes using references.


    "...the adversities born of well-placed thoughts should be considered mercies rather than misfortunes." Don Quixote
Re: reference , advantages?
by ikegami (Pope) on Jun 30, 2011 at 18:00 UTC

    What is the advantage of this reference use or in general

    Compared to what?

    why are reference useful compared to scalars?

    References are scalars, so the question makes no sense.

    $fref = \...; if ( $$fref ) {

    There isn't a reason to use a reference here, but it could be that you left out relevant pieces of the original code.

Re: reference , advantages?
by Sandy (Curate) on Jun 30, 2011 at 18:10 UTC
    Sometimes it is advantageous to use code-refs.
    #!/usr/bin/perl use strict; use warnings; my $dref = \&new_date; my $fref = \&new_date_append; # call function foo, print different types of date foo ($dref); foo ($fref); sub new_date { my ( $year, $month, $day ) = (localtime)[ 5, 4, 3 ]; sprintf( "%04d%02d%02d", ( $year += 1900 ), $month + 1, $day ); } sub new_date_append { my $date = new_date(); return "OhioS___$date"; } sub foo { my $date_fn = shift; print $date_fn->(),"\n"; }
    Note

    $dref=\&new_date is a reference to SUBROUTINE, $dref=\&new_date() is reference to the SCALAR returned by the subroutine

Re: reference , advantages?
by TomDLux (Vicar) on Jun 30, 2011 at 17:52 UTC

    In new_date_append(), you are assigning a value to $monster_date, which is an undeclared variable, as far as I can see. Why aren't you getting an error message about that? That assigned value uses a global variable named $passed_new-date, which is not passed at all. The new value then becomes the return value of the routine.

    $fref is assigned a reference to the subroutine, which might then be invoked as $fref->(); $$fref is meaningless and should generate an error.

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

      Actually, if you assume that the <snip> has the proper declarations, the $fref is a reference to the returned string from the function and $$fref is the string.

      Cleaned code

      #!/usr/bin/perl use strict; use warnings; my $passed_new_date = new_date(); my $fref = \&new_date_append(); ###--- HERE is my REF ---### sub new_date { my ( $year, $month, $day ) = (localtime)[ 5, 4, 3 ]; sprintf( "%04d%02d%02d", ( $year += 1900 ), $month + 1, $day ); } sub new_date_append { return my $monster_date = "OhioS$passed_new_date"; } if ( $passed_new_date and $$fref ) { print $$fref,"\n"; }
      Result
      >perl ref.pl OhioS20110630
Re: reference , advantages?
by armstd (Friar) on Jul 01, 2011 at 19:01 UTC

    I do suppose the OP is more interested in sub refs, but hey. Since everyone else wants to talk about refs in general...

    The thing I like about references is that they can be used consistently throughout.

    You cannot build a list of lists, you can only build a list of ARRAYrefs. Same for associative arrays. Might as well start with an ARRAYref of ARRAYrefs, and avoid the confusion of inconsistent referencing based on context.

    I've tried to adopt a coding style of using refs everywhere, and dereferencing where necessary. Ok, maybe not so much for subs or globs, but definitely for arrays and hashes. I typcially name my reference vars by the type of structure they represent for clarity (list/hash). This way anyone maintaining my code can see that everything is done consistently. No need to change syntax when passing stuff around, or refactoring a structure, etc. Too many bugs I've seen came from inconsistent dereferencing, since Perl is perfectly happy treating refs, arrays, and hashes all as scalars. No syntax error here, just crap code. Sorry.

    Sometimes its hard to resist the pull of non-refs... It's just so convenient sometimes that builtins like sort/map/split return structures. Initializing references from the return of those builtins is just awkward stylistically/syntactically. Oh well, that's consistent too at least.

    --Dave

Re: reference , advantages?
by sundialsvc4 (Abbot) on Jul 01, 2011 at 13:33 UTC

    You most likely use references a lot more than you realize, just in the ordinary course of using Perl to do anything.   A reference is not only “a way to have one thing at two or more places at one time,” but also a very light-weight way to “carry a thing around” without actually copying it and carrying it.   As long as you are aware and mindful of the weaken method (in Scalar::Util), and the small issue of cyclic memory references, it all works very well indeed.

    Computer programs often get buzzed about being “computationally” inefficient, even though the real cause of delay is almost invariably either I/O-wait or page-fault-wait.   The smaller your program’s working-set is, and the more stable it is, the more efficiently it will be able to run.   So, it is very advantageous indeed to be able to have just one copy of “that million-page elephant” lying about, and to only deal with references to it ... which are tiny, and free.

    The dis-advantage, which you also need to be aware of, is that when two variables refer to the same thing, they are basically EQUIVALENCEd, borrowing the Fortran term ...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://912216]
Approved by Corion
Front-paged by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2021-04-23 06:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?