Ok, so we have a field in our database called file_format and it is a string that when evaluated and $b is defined, will return a patch name with the bug number filled in.

The problem is that over time each person's way of putting $b into this template string varied based on their personal tastes. So we have all of the following in this column in the database.

p${b}.zip p{$b}.zip p$b.zip
and the problem with this comes when you want to create a SQL SELECT statement to pull out a row when one of the join criteria is this column. Because, instead of writing:
SELECT * FROM table WHERE file_format='p$b.zip'
I have to write
SELECT * FROM table WHERE file_format='p$b.zip' or file_format='p{$b}.zip' or file_format='p${b}.zip'

and I have the willies because I'm not sure if I have covered all the ways that such variable interpolation can take place.

On the other hand, you might comment on my dilemma as a lesson in business logic as discussed in davorg's "Data Munging with Perl". All business logic should be in classes and hence the policy for this field read and write processing should have been in a class where the template string was generated in invariant Perl code as opposed to however it was done here (I wasn't around when it was done and don't want to stress anyone in this poor economy for fear of being kicked out into the streets).

Replies are listed 'Best First'.
(Ovid) Re: TMTOWTDI isn't best in this case
by Ovid (Cardinal) on Jul 24, 2001 at 02:41 UTC

    Yes, it's really miserable when programmers don't adopt a solid set of standards and don't bother to group the business logic in one area. However, if these are all the ways you have this done, then your problem should be simple. Consider this code:

    my $b = '7'; print "p{$b}.zip\np${b}.zip\np$b.zip";

    That prints the following:

    p{7}.zip p7.zip p7.zip

    As you can see, when interpolating variables, ${b} and $b are the same (for this particular instance), so you won't have to check for both of them. However, p{$b} has the braces included in the string. In addition to MeowChow's nice fix, you could check file_format and if you don't have a format the genuinely matches /^p\{[^}]+\}\.zip$/, then you should be able to write a bit of code that patches the data. However, you'd then have to search through your code for anything that works with that table and is expecting the corrupted format.

    I am wondering, though, why you have a SELECT * in the code. If you don't need all of the fields, it's wasteful. If you do need all of the fields, then someone adding, switching, or dropping fields could easily break the code if this is not properly accounted for. Further, even if you do need all of the fields, specifying the names of the fields makes the code more self-documenting.

    HTH

    Cheers,
    Ovid

    Vote for paco!

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

Re: TMTOWTDI isn't best in this case
by cforde (Monk) on Jul 24, 2001 at 03:27 UTC
    You could try this
    SELECT DISTINCT file_format FROM table
    That would tell you all the methods of variable interpolation that have been used. Then use
    UPDATE table SET file_format='p$b.zip' WHERE file_format IN (....)
    to put them into a consistent format. Then update your procedures so it doesn't happen again. Or maybe you want to do that first?

    Have fun,
    Carl Forde

(MeowChow) Re: TMTOWTDI isn't best in this case
by MeowChow (Vicar) on Jul 24, 2001 at 02:31 UTC
    Depending on your SQL implementation and your performance requirements, you could consider doing something like:
      
    SELECT * FROM table WHERE file_format LIKE 'p%$b%.zip'
       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print
      Your SELECT will miss this case:
      p${b}.zip
      which is one of the ones I listed.

      And while I'm replying to things, Ovid, the SELECT * was just an example of what I'm doing, I am being explicit about which rows I am getting.

        But p${b}.zip is the same as p$b.zip, thus interpolating $b and eliminating the braces. If you're unsure of this, you can do the following:

        my $b=7; print ${b};

        That prints 7, thus making MeowChow's solution a viable one. I know it looks odd, but it's valid Perl and it works with warnings and strict. I'm using 5.6.1. Does this fail on other versions of Perl?

        Cheers,
        Ovid

        Vote for paco!

        Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

        I originally had it as 'p%b%', but changed it after thinking (apparently incorrectly) that $b was an interpolated value. Implementation trivia notwithstanding, the principle is the same.
           MeowChow                                   
                       s aamecha.s a..a\u$&owag.print
Re: TMTOWTDI isn't best in this case
by eejack (Hermit) on Jul 24, 2001 at 06:50 UTC
    For an entirely different twist on the matter, why don't you write a script to pull all of the offensive bits out, fix them and put them back.

    Once they are all fixed, then you don't have to sweat it one way or another.

    While you are at it, you might write a subroutine that will force it to stay proper in the future. A little extra effort now might/could save you some grief later.

    EEjack

(ichimunki) Re: TMTOWTDI isn't best in this case
by ichimunki (Priest) on Jul 24, 2001 at 15:58 UTC
    Except that in this case TIMTOWTDI doesn't apply because your example produces two different end results-- which is NOT a case of doing "it", it's a case of doing different stuff. The best case here has nothing to do with Perl or its motto. It has everything to do with programmers learning to say what they mean with their code, since I expect whoever wrote {$b} didn't intend to insert {}'s into a filename, but thought they were using the ${b}. Or maybe it was an undetected typo. Even -w can't catch it when it results in valid syntax (the old too, two, to spellchecker problem).