in reply to Re: I put the J in JAPH
in thread I put the J in JAPH

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

Replies are listed 'Best First'.
Re^3: I put the J in JAPH
by liverpole (Monsignor) on Sep 18, 2005 at 18:15 UTC
    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.

        Excellent!  I have one request -- can you explain the magic you're doing with AUTOLOAD, and what you mean by "vstrings"?  I haven't used AUTOLOAD much, (I actually *did* think about using it for this obfuscation) so I'd appreciate knowing more!

        Updated:  Here's what I have so far:
        #!/usr/bin/perl -w + use warnings; + my $text; my @a = ( sub {$text = $_[0]}, # Assign text to $1 sub {$text = $_[0] . $text}, # Prepend text with $1 sub {$text .= "\n"; shift}, # Appends "\n" to text sub {$text =~ s/$_[1]//; print $text} # Remove $1 from text, pri +nt text ); + sub AUTOLOAD { *{$AUTOLOAD} = shift(@a); goto &$AUTOLOAD } + foreach my $subname (v74, "put", "the", "RAPH") { *{$subname.'::AUTOLOAD'} = \&{'AUTOLOAD'} } + I put the J in RAPH and remove the R

      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