Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Bless and Do

by zeltus (Beadle)
on Jun 17, 2014 at 15:59 UTC ( [id://1090163]=perlquestion: print w/replies, xml ) Need Help??

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

Looking thru' some legacy code I have to support, I have come across entries like...

$variable = bless( do{\(my $x = 49)}, 'Rates::Notification

I am unclear what the 'do' is for

I have a vague memory of tutorials involving inside-out programming, blessing of scalars and such-like which I think have a bearing on this, but my memory is shot and I can't remember anything else.

Can a Monk put me out of my misery and explain why this was used and why it should (or shouldn't) be used today?

thanks!

Replies are listed 'Best First'.
Re: Bless and Do
by kennethk (Abbot) on Jun 17, 2014 at 16:08 UTC
    The do block defines the logical context of the my declaration. Essentially, we:
    1. define $x
    2. assign the value 49 to it
    3. take a reference
    4. let $x go out of scope
    5. bless the reference
    6. store the reference

    Since Perl does not have the concept of an anonymous scalar ref (in contrast to {} and []), your kludge is one way of getting that. The best reason to use it is because it works. The worst reason is that you had to ask the question; it doesn't scan unless you know the trick. Were I to write it, I'd probably go with the more verbose:

    my $variable; ANON_SCALAR_BLOCK: { my $x = 49; $variable = bless \$x, 'Rates::Notification'; }
    If you really want to use a do, you could also
    my $variable = do { my $x = 49; bless \$x, 'Rates::Notification'; };
    which I think scans better.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      An interesting thing to note: Data::Dumper uses a form very similar to OP with blessed references.

      perl -MData::Dumper -e 'print Dumper bless \((49)[0]), "Rat::Notificat +ion";' $VAR1 = bless( do{\(my $o = 49)}, 'Rat::Notification' );

      If you really want to use a do, you could also

      my $variable = do { my $x = 49; bless \$x, 'Rates::Notification'; };
      which I think scans better.

      Yes, do on the outside always scans better, its like creating a sub and calling it immediately,  (sub { ... })->(); except prettier :)

        > Yes, do on the outside always scans better, its like creating a sub and calling it immediately, (sub { ... })->(); except prettier :)

        To avoid misunderstandings: It's similar but not identical!

        DB<106> sub tst { (sub { return 5 })->(); return 10 } DB<107> tst() => 10 DB<108> sub tst { do { return 5 }; return 10 } DB<109> tst() => 5

        Like with map and grep is the block following do not an anonymous sub!

        Cheers Rolf

        (addicted to the Perl Programming Language)

Re: Bless and Do
by LanX (Saint) on Jun 17, 2014 at 16:08 UTC
    One can bless only references, but all kind of references!

    While the "standard" is to bless hash-refs, there are occasions where blessing array-refs or code-refs or even scalar-refs make much sense.

    BUT there is no "literal notation" for scalar-refs (like [...] or sub{...} )!

    That's why a do construct is used, to avoid temporary variables¹.

    IIRC does TheDamian talk about this in his (recommended!) PBP book.

    HTH! :)

    Cheers Rolf

    (addicted to the Perl Programming Language)

    update

    ¹) like

    $temp_scalar = 5; my $scalar_ref = \$temp_scalar; bless $scalar_ref, ...
Re: Bless and Do
by NetWallah (Canon) on Jun 17, 2014 at 17:03 UTC
    If you are not using $_ in the local block, this should meet the need to avoid temporary variables, while maintaining readability, and avoiding "do":
    my $variable=bless \(local $_=49) ,'Rates::Notification';
    As mentioned before, the assignment is necessary to avoid "Modification of a read-only value attempted at ..".

    If you are using $_, then the previous recommendations apply, in order to reduce the scope of the local assignment.

            What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?
                  -Larry Wall, 1992

Re: Bless and Do
by Bloodnok (Vicar) on Jun 17, 2014 at 17:06 UTC
    I don't believe that I have anything to add to what other monks (at the time of writing - kennethk and LanX) have already said other than to add that, in such circumstances, I tend to use the construct bless \(my $me), ... over the update provided by LanX to his post.

    A user level that continues to overstate my experience :-))

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1090163]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-20 02:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found