http://www.perlmonks.org?node_id=1069486

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

#!/usr/bin/perl -w use strict; use warnings; use feature "switch"; my$z = "d"; my($a,$b,$c,$d,$e) = split(//, $z); given($a eq "a" || "b"|| "c" || "d"|| "e"||"f" || "g"|| "h"||"i" ||"j" + || "k"|| "l"||"m" || "n"|| "o"||"p" || "q"|| "r"||"s" || "t"|| "u"|| +"v" || "w"|| "x"||"y" || "z"){ when ('a'){ print "1";} when ('b'){print "2";} when ('c'){print "3";} when ('d'){print "4";} when ('e'){print "5";} when ('f'){print "6";} when ('g'){print "7";} when ('h'){print "8";} when ('i'){print "9";} when ('j'){print "10";} when ('k'){print "11";} when ('l'){print "12";} when ('m'){print "13";} when ('n'){print "14";} when ('o'){print "15";} when ('p'){print "16";} when ('q'){print "17";} when ('r'){print "18";} when ('s'){print "19";} when ('t'){print "20";} when ('u'){print "21";} when ('v'){print "22";} when ('w'){print "23";} when ('x'){print "24";} when ('y'){print "25";} when ('z'){print "26";} default{print 'Everything else'} }
When i executing this script i'm getting output only  2 . Please let us know.

Replies are listed 'Best First'.
Re: Not getting desire output by using switch statement in Perl
by Eily (Monsignor) on Jan 06, 2014 at 12:02 UTC

    $a eq 'a' || 'b' does not mean "$a is equal to ('a' or 'b')" but rather "return true if $a is equal to 'a', or return 'b'", which means everytime $a fails to match 'a', 'b' is returned instead. Your code would work with:

    given ($a) { when ('a') { print 1}; when ('b') { print 2}; ... }
    But given is experimental (Edit: I first wrote deprecated, but choroba pointed out the mistake), so you shouldn't use it. And the fact that you had to do 26 times the same thing (I hope you used copy and paste) is a clear indication that there is something wrong with your code. And you should not have variables called $a and $b, perl has other uses for them, and might change their values without warning.

    Here is a simpler solution using ord

    $\ = "\n"; # add a line break after each print, say could be used inst +ead for my $char (split //, "Hello World") { if ($char =~ /[a-z]/) # if the char is between a and z { print 1 + ord($char) - ord('a'); } else { print "Else"; } }
    It could be even shorter, but I believe this will be easier to understand.

      i don't get how it works this script for case. Please could explain your script ... when i execute your script I'm getting this output
      Else 5 12 12 15 Else Else 15 18 12 4
      . What this output could you please explain this..

        How does the output differ from the output you expect?

        For example, it seems to me that e should map to 5 and l should map to 12 from your problem description.

Re: Not getting desire output by using switch statement in Perl
by choroba (Cardinal) on Jan 06, 2014 at 11:40 UTC
    Your condition is not doing what you think:
    perl -MO=Deparse,-p -e '$a eq "a" || "b" || "c" || "d"' (((($a eq 'a') or 'b') or 'c') or '???');
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Then how I'm achieve that result?(me question is if I give a string then it returns output result with numeric values like based on alphabetic value in numeric type- a is 1, b is 2,c is 3 in this similar way up to..... z is 26 )
        Easy. See ord:
        if ($a =~ /[a-z]/) { print ord($a) - 96; } else { print "Everything else"; }
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Not getting desire output by using switch statement in Perl
by dasgar (Priest) on Jan 06, 2014 at 13:56 UTC

    Although others have suggested using ord, I would have used a different approach by using Number::Latin.

    The code below looks at a character and if its an alphabet (a-z), it will convert it to an integer (regardless of case) and print it. And it will print the string "Something else" if the character is not an alphabet character.

    use strict; use warnings; use feature 'say'; use Number::Latin; my $string1 = 'abcdef ghijkl-mnopq,rstuv.wxyz'; my $string2 = uc($string1); say $string1; for my $char (split //,$string1) { if ($char =~ /[a-zA-Z]/) {say latin2int($char);} else {say "Something else"} } say $string2; for my $char (split //,$string2) { if ($char =~ /[a-zA-Z]/) {say latin2int($char);} else {say "Something else"} }
Re: Not getting desire output by using switch statement in Perl
by Lennotoecom (Pilgrim) on Jan 06, 2014 at 19:27 UTC
    as an option
    %a = map {$_ => ++$i} a..z; chomp($_ = <STDIN>); exists $a{$_} ? print "$a{$_}\n" : print "Everything else\n";
      You can use the ternanry operator to save you typing print twice:
      print exists $a{$_} ? $a{$_} : 'Everything else', "\n";

      This is how I use the ?:.

      لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
        awesome, thank you
Re: Not getting desire output by using switch statement in Perl
by dbuckhal (Chaplain) on Jan 07, 2014 at 06:11 UTC
    Tired and should be doing homework, but...
    $ perl -le '$alpha = "abcdefghijklmnopqrstuvwxyz"; $str = "This is a String"; print grep { ($_) } map { 1 + index($alpha, $_), "\n" } split //,lc($str)' __output__ 20 8 9 19 9 19 1 19 20 18 9 14 7
    Perl is so fun...