Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re^4: Module Announcement: Perl-Critic-1.01 (scalar)

by tye (Sage)
on Jan 26, 2007 at 22:45 UTC ( #596798=note: print w/replies, xml ) Need Help??

in reply to Re^3: Module Announcement: Perl-Critic-1.01 (just a scalar)
in thread Module Announcement: Perl-Critic-1.01

Do you write the following?

my %hash= ( key1 => scalar lc $value );

If not, then it is probably because you know that 'lc' just returns a scalar. If you do, then there are probably a lot of people who find you silly. 'lc' isn't the only function I use that just returns scalars. Sprinkling 'scalar' all over hellenbach doesn't improve code much in my experience.

I actually consider the => to be broken for not enforcing scalar context on both sides. But that still just shifts the problem to things like function arguments.

Why haven't you written a 'string' function that forces all arguments to be treated as strings and asserts if given a reference? And an 'integer' and 'float' function that asserts when given things not appropriate for those context? Then you can fix all of your broken assumption-filled code:

if( boolean( integer($scale) < integer(scalar getMaxScale()) + ) || boolean( scalar isExempt() ) ) { Report( string( scalar getName() ), float( (integer($base)+integer($bonus)) / integer($count) +), ); }

Yes, that code looks much easier to maintain. [Oops, I left off one boolean().]

And what about all of those places where my list context is implicit? Surely those need to be made explicit too? I'll write partOfList() that asserts if not called in a list context.

if( boolean( integer($scale) < integer(scalar getMaxScale()) + ) || boolean( scalar isExempt() ) ) { Report( partOfList( string( scalar getName() ) ), partOfList( float( (integer($base)+integer($bonus)) / integer($cou +nt) ) ), ); }

Now, there are places where using scalar() is more appropriate. But, no, I don't consider using it on a function that just returns a scalar to be such a place. And I don't think transforming every function that might want to return an undefined scalar into "a function that returns a scalar except when it wants to return a undefined scalar in which case it returns an empty list instead and if you really wanted the undefined scalar then you should wrap the call in scalar() for that purpose" to be even close to an improvement strategy.

- tye        

Replies are listed 'Best First'.
Re^5: Module Announcement: Perl-Critic-1.01 (scalar)
by rir (Vicar) on Jan 27, 2007 at 01:35 UTC
    Your position is problematic because your model ignores a fundamental, from perlsub: The Perl model for function ... return values is simple: ... all functions ... return to their caller one single flat list of scalars.

    lc doesn't return a scalar it returns a one element list.

    Be well,

      That statement doesn't contradict my position. I never said that a single scalar can't also be considered as a list. I'm not playing some semantic game. I'm talking about practical implications.

      If we want to play your semantic game, then replace "scalar" with "single-item list" throughout what I wrote (which requires patching Perl to rename the scalar() function, but such is life).

      If you have a function that always returns exactly one item (as the list of items that it returns), then it doesn't make sense to change this function to return a zero-item list in one special case. (Why? Read what I wrote above.)

      lc doesn't return a scalar

      Repeat that to a few random people who know Perl and see how silly this particular semantic argument is. lc() always returns just a scalar. The list of scalars that lc() returns always has a size of one. Those are both true. *shrug*

      - tye        

        If you have a function that always returns exactly one item (as the list of items that it returns), then it doesn't make sense to change this function to return a zero-item list in one special case.

        That's not what return; does. It returns something that's false in boolean, scalar, and lists contexts. I know you know this; it just seems valuable to be very explicit about what we're discussing.

        Now (on topic), it's difficult for Perl::Critic to recognize the semantic need for that with regard to any single specific Perl function. It seems like a variant of the semi-predicate problem; what does return undef; mean?

        Damian's rule is Use a bare return to return failure. I believe that's good advice.

        Other than populating lists about to become hashes, what advantages do you find with the explicit return undef convention?

        I wasn't trying to contradict you, play semantic games, nor make a silly argument. My concern was that your statements would mislead people with less understanding of the context issue.

        Perhaps, I was too brief before, because

        my %hash= ( key1 => genValue1(), key2 => genValue2() };

        was an obviously made-up example and I didn't care to pick at it.

        Why couldn't genValue1() generate a solitary first value or die and so conform to a bare return convention? Update: which is just to say either convention is workable; also key => val() || undef,

        Be well,

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://596798]
[choroba]: yes, I've read about it and its probable original form
[Discipulus]: Tomas in greek ~140Ad
[Discipulus]: also the 'today bred' was probably 'tomorrow's bred'
[LanX]: Novum Testamentum Graece
[erix]: "give us today our bread from tomorrow" -- that's not going to fly

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (10)
As of 2017-11-23 20:46 GMT
Find Nodes?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:

    Results (338 votes). Check out past polls.