in reply to I put the J in JAPH

You can add in strict and warnings thusly. Plus, I trimmed and obfuscated a tad more:

use strict; use warnings; sub I{print@_,chr(0x0a)}sub remove{}sub put{shift=~m/^\w+\s(.)\s\w+\s.(.+)/ix;} I put "the J in RAPH" and remove "the r"

On second thought, it might be more fun if remove did what it said it did...

Replies are listed 'Best First'.
Re^2: I put the J in JAPH
by muba (Priest) on Sep 18, 2005 at 16:39 UTC
    On second thought, it might be more fun if remove did what it said it did...

    I agree, and have thought about that, but I decided that would be too much fuss :)
    Furthermore, I don't know how to let remove() remove the "r" but with 'and' still working.




    "2b"||!"2b";$$_="the question"
    Besides that, my code is untested unless stated otherwise.

    magnum unum bovem audivisti
      I thought your idea extremely clever.

      It occurred to me that you could remove ALL of the quotation marks, by carrying the idea further ...

      sub I {$O=$_[0]} sub put {$_[0]} sub the {$_[0]} sub J {'J'.$_[0]} sub in {$_[0]} sub RAPH {82.65.80.72} sub remove {$O=~s~$_[0]~~;print$O."\n"} sub R {'R'} I put the J in RAPH and remove the R
      How it works ...
      First, delineating the order of evaluation:

        Expression:  (I (put (the (J (in (RAPH)))))) and (remove (the (R)))

      Subroutines "put", "the" and "in" just return their single argument, so they are all effectively NOOPs. This reduces the expression to:

        Expression:  (I ( ( (J ( (RAPH)))))) and (remove ( (R)))

      = Expression: (I (J RAPH)) and (remove R)

      Now, subroutine "RAPH" returns "RAPH", and subroutine "J" prepends a 'J' to the argument passed to it. So (J RAPH) equates to "JRAPH":

        Expression:  (I "JRAPH") and (remove R)

      Then, subroutine "I" assigns its argument to $O (the variable is an uppercase 'o', for "obscure:, "obtuse", and "obfuscated" :-).  Finally, the subroutine "remove" takes a single argument (in this case 'R', which was returned from subroutine "R"), removes it from the variable $O, and prints the result.

          Result:  [$x set to "JRAPH"] and [$x =~ s/R//, and then print $x]

      Note that it also causes remove() to actually perform the remove.

        I like it a lot, but it seems very clear what is happening... you are explicitly mapping each of the words to a function. With the help of indirect objects and AUTOLOAD, you self-map a bit, muddy the waters, and avoid repeating yourself:

        use warnings; @a=(sub{$O=$_[0]},sub{$O=$_[0].$O},sub{$O.=$/;shift},sub{ ($_=$O)=~s~$_[1]~~;print});*{$_.q;::AUTOLOAD;}=sub{shift( @a)->(@_)}for(v74,112.117.116,116.104.101,82.65.80.72);#! I put the J in RAPH and remove the R

        Some downsides/challenges: you have to spell out the objects (which I cheat with vstrings--), and I've lost my use strict; and I don't think that it can be massaged back in. Can anyone think of a way to grab package names as they autoviv?

        Update: trimmed some fat.

        Explanation for liverpole:

        What is actually being called in this is as follows (in this order:

        1. RAPH::in()
        2. J::the( ... )
        3. put::I( ... )
        4. the::remove('R')
        # de-munged a bit: *{$_."::AUTOLOAD"} = sub { shift(@a)->(@_); } for qw{ J put the RAPH };

        For each required package I am creating an AUTOLOAD that simply calls the next sub in my action stack. In the case of RAPH::in() and J::the() the calling package is our payload. I had a mess of indirection in there before, but I've golfed it down.

        Ok, this is really cool!
        But I don't quite get it. I understand how the expression works and that some subs are basically NOOPs, but I don't get how the f**k you get s**t printed without ever using print. :)

        Edit: now I get it. Remove does the printing. Awesome!




        "2b"||!"2b";$$_="the question"
        Besides that, my code is untested unless stated otherwise.

        magnum unum bovem audivisti