Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: RFC: Tutorial: use strict; now what!?

by moritz (Cardinal)
on Feb 08, 2012 at 09:50 UTC ( [id://952448]=note: print w/replies, xml ) Need Help??


in reply to RFC: Tutorial: use strict; now what!?

Very nice.

From my experience though, beginners who use soft references should be using hashes instead, not hard references. It would be useful to add that solution too.

  • Comment on Re: RFC: Tutorial: use strict; now what!?

Replies are listed 'Best First'.
Re^2: RFC: Tutorial: use strict; now what!?
by JavaFan (Canon) on Feb 09, 2012 at 00:04 UTC
    beginners who use soft references should be using hashes instead,
    Hashes can be the solution. However, in almost all cases a hash based solution is done is such away it has all the disadvantages of not using strict, and none of the advantages.

    Writing $hash{key} isn't any better than no strict; $key. In fact, it's worse. If you don't have strict enabled, and you typo and write $kye (once), you still get a compile time warning (assuming they are enabled). If you typo $hash{kye}, at best you get a runtime warning of an uninitialized value, depending on how it's used. But you may get no warning or error, regardless whether you have strict or warnings enabled.

    Only if you would write:

    my $KEY = "..."; ... $hash{$KEY};
    you get protected against typos, but I very seldomly see people using hashes that way. But then you still don't get all the benefits of using regular, lexically scoped, variables:
    my $KEY1 = "something"; ... my $KEY2 = "something"; ... $hash{$KEY1} = "..."; $hash{$KEY2} = "..."; # Ooops.
    Perl will warn you if you declare a variable with the same name in the same scope. A benefit you lose if you implement variables as hash keys.

    For me, code that uses hashes as if the entries were variables is a red flag. It indicates the most dangerous type of programmer. It's someone who thinks he's past the grasshopper stage, but really isn't yet.

    Hashes as a bag of variables should be treated as Fugu. Only after 25 years of training, the first 14 of which all you do is cook rice 16h/day, 365 days/year are you allowed to look at the fish, and it takes another 25 years to master the slicing. Aka, it's only the experts, and they usually won't do it. It's certainly not for beginners.

    I rather see someone using a soft reference, than a hash as a bag of variables. That cure is worse than the disease.

      However, in almost all cases a hash based solution is done is such away it has all the disadvantages of not using strict, and none of the advantages.

      I disagree. Most beginner's uses of soft references are along the lines of

      while (<>) { while (/([a-z]+)/g) { my $word = $1; $$word++; } } print "I've seen the word 'compiler'\n" if $compiler; # similar checks for a few other variables here

      If you do that with a hash instead, you have a very clear benefit: you don't run into the risk of accidentally changing any our-scoped scalars in the current package.

      I am trying to follow this as I use hashes all over the place. What exactly is a soft reference. Perldoc says this:
      Symbolic references are names of variables or other objects, just as a symbolic link in a Unix filesystem contains merely the name of a file. The *glob notation is something of a symbolic reference. (Symbolic references are sometimes called "soft references", but please don't call them that; references are confusing enough without useless synonyms.)
      I understand the difference between hard and soft links in a filesystem, but in Perl?
        $foo = 23; $soft = 'foo'; # soft reference $hard = \$foo; # hard reference print "soft=$$soft, hard=$$hard\n";
        A soft reference holds a variable's name, while a hard reference holds its memory address. When you dereference a soft reference, you search for a name in the symbol table. When you dereference a hard reference, you fetch the variable at that address.
        I am trying to follow this as I use hashes all over the place. What exactly is a soft reference.

        tangent, you'll get plenty of explanations of symbolic references. But even after you understand them well it may not be clear how hashes come into this, in almost the same breath.

        To recap, moritz offered hashes as an alternative to hard references. There was some discussion of this and JavaFan noted hashes can invite some of the same issues strict 'refs' is meant to avoid. You may not see the connection; it took me a moment to pick it up.

        Seen one way, use strict; is a typo-catcher. In the simple case:

        our $x13 = 'foo'; print $x31;

        ... may not work as you expect because you really meant to type $x13 both times. But use strict; will complain that you did not declare $x31 and so the typo is caught.

        If you attempt to take a hard reference and make a typo, you'll get an error, too. But if you take a symbolic reference and don't use strict; then you will not get early notice of your typo.

        Where hashes begin to resemble (in a certain mental state) symbolic references is when you start stuffing a lot of unrelated data into a hash with literal keys; and then later you want to take something out:

        my %hash; $hash{boy} = 'Arnold'; $hash{pension_balance} = 172.50; $hash{filehandle} = $fh; print $hash{pensionbalance};

        The typo will not be caught, with or without use strict; instead, perl will happily autovivify $hash{pensionbalance} for you and immediately print it... although it's undefined. This can be an annoying thing to track down.

        For more on this, see Re: Accessing hash from within module, where I demonstrate exactly this kind of risky approach... and note that it's almost as evil as global variables. I would not even have mentioned it if the OP didn't seem solidly committed to globals in the first place. As questionable as it is, I still think it's better than no strict 'refs';

        I'm not the guy you kill, I'm the guy you buy. —Michael Clayton
      I rather see someone using a soft reference, than a hash as a bag of variables.

      Except that you can only use symbolic references with package globals in Perl 5, so you're susceptible to the risks of action at a distance.

        Is that suppose to say "Perl 6" where you said "Perl 5"?

        Nevermind.

      However, in almost all cases a hash based solution is done is such away it has all the disadvantages of not using strict

      Not even close.

      How is the following remotely the same as a program without strict:

      while (<>) { my ($k, $v) = split; $h{$k} = $v; } for my $k (keys(%h)) { ... $h{$k} ... }
        It's not so hard:
        package P; while (<>) { my ($k, $v) = split; $$k = $v; } for my $k (keys(%P::)) { ... $$k ... }
Re^2: RFC: Tutorial: use strict; now what!?
by Xiong (Hermit) on Feb 08, 2012 at 10:11 UTC

    Thank you, moritz. I have given, in each of the three examples, code that fails a stricture; and a solution that passes strictures with exactly the same output as the failing code under no strictures. I'm not sure that's wise; it's merely simple.

    I'm a little afraid to step into the tar pit of Here are some of the things you might have been meaning when you got this error and here are some possible solutions. I did have the impulse and I agree that it might be helpful. Perhaps another node?

    If I see a proposed example and solution illustrating a strict 'refs' violation using a hash, I'll be glad to substitute it.

    I'm not the guy you kill, I'm the guy you buy. —Michael Clayton
      I was going to say the same thing as moritz. In the spirit of your example, here is perhaps what was meant:
      my $pet = 'dog'; my %pet_name; $pet_name{$pet} = 'Rover'; print "$pet_name{dog}\n";

        Please show me the matching problem code?

        I'm not the guy you kill, I'm the guy you buy. —Michael Clayton

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2024-04-18 18:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found