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

With the help of @lzh on #perl I got this peace :
perl -we '$tty=qx(tty); $tty=~s/.*d...(.*)/$1/; print $tty'
to yield the pts/# out of tty's output(/dev/pts/#). I was just wondering if anyone would come up with something different or even faster. I have question though, why is $1 better than \1? \1 works, but Perl suggest using $1.

Replies are listed 'Best First'.
Re: More than one way to do it???
by kilinrax (Deacon) on Dec 07, 2000 at 02:38 UTC
    An immediate improvement that springs to mind is in the regex - change it to simply remove the '/dev/' at the beginning of the string:
    perl -we '$tty=qx(tty);$tty=~s!^/dev/!!;print $tty'
      Hum! Obviously, sleek...
Re: More than one way to do it???
by Fastolfe (Vicar) on Dec 07, 2000 at 02:42 UTC
Re: More than one way to do it???
by FouRPlaY (Monk) on Dec 06, 2000 at 23:24 UTC
    If my understanding of merlyn's book and or posts (I can no longer remember which, or even if it was merlyn); you use \1 on the "right hand part" of s///, and $1 on the "left hand part."

    Uh, so for getting rid double words you'd use:
    s/(\w+)\s+\1/$1/
    Or something.

    But then again, I could be horribly, horribly, wrong.



    FouRPlaY
    Learning Perl Or Going To die() Trying

      Actually you have to use \1 in the left part, you can't use $1, but you can use either \1 or $1 in the right part.

      $1... cannot be used in the left part because it would be expanded (the $1 from the previous regexp) and usage of \1 in the right part is mildly frowned upon, mostly for stylistic reasons, as it is close to the \nn or \nnn notation for octal characters (although as usual Perl will DWIM by interpreting \12 as $12 if there were more than 12 captured expressions and as the character \12 otherwise).

        This is correct. According to the Camel book, the right hand side of a substitution (//) is considered to be outside of the regex. So the "special" variable (i.e. \1) is treated as a "normal" scalar variable thus it can be interpolated there because this side functions as if it was a double quoted string.
Re: More than one way to do it???
by Fastolfe (Vicar) on Dec 07, 2000 at 01:08 UTC
    You can use the ttyname() function in POSIX to get this:
    use POSIX; $tty = ttyname(0);
Re: More than one way to do it???
by Albannach (Monsignor) on Dec 06, 2000 at 23:27 UTC
    I believe the reason $1 is better is that \1 is not necessarily going to be valid beyond the pattern it came from.
Re: More than one way to do it???
by marius (Hermit) on Dec 07, 2000 at 00:50 UTC
    i modified the regex to be s#.*/(.*)#$1#, and it seems to work for me.

    Incidentally, perl complains about the \1 because you are doing it from the command line, and your shell is subject to processing escape characters as well. If you put the code above into a file, and do perl file.pl, it doesn't complain about using a \1.

    -marius
      That explanation isn't accurate. Perl complains about using \1 in the right-hand side of a substitution because using $1 is preferred. Whether the script is entered on the command line or not isn't important.
      #!perl -w use diagnostics; $_ = 'foo'; s/(.)/\1/;
      This script produces the following output:
      \1 better written as $1 at tmp.pl line 5 (#1) (W) Outside of patterns, backreferences live on as variables. The + use of backslashes is grandfathered on the right-hand side of a substitution, but stylistically it's better to use the variable fo +rm because other Perl programmers will expect it, and it works better if there are more than 9 backreferences.
Re: More than one way to do it???
by slocate (Novice) on Dec 07, 2000 at 12:34 UTC
    Just came up with, should perl I say, version .02, though i think it's getting a little "$obfuscated" already, let me know:  perl -we '$tty=qx(tty);$tty=~s/^\W\w+\W//;print $tty'
Re: More than one way to do it???
by slocate (Novice) on Dec 07, 2000 at 13:18 UTC
    Well after tinckering with it some more i came up with this, which I think is already getting a bit $obfuscated: perl -we '$tty=qx(tty);$tty=~s/^\W\w+\W(.*)/$1/;print $tty' By the way, I wanted to thank all of those who have taken the time to ponder on my node. This is needless to say a great community. I'm glad I stumbled into it, though I'm yet to find out the turns that have around.
Re: More than one way to do it???
by jeffa (Bishop) on Dec 07, 2000 at 00:31 UTC
    Can't help you with a faster or different version, but I believe the \1 is an old awk/sed variable, it's probably available in Perl simply for historical reasons. Also, vi uses \1.