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

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.

Replies are listed 'Best First'.
Re^4: I put the J in JAPH
by fishbot_v2 (Chaplain) on Sep 19, 2005 at 14:00 UTC

    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

Re^4: I put the J in JAPH
by muba (Priest) on Sep 18, 2005 at 18:34 UTC
    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