Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: footer on Joel's email

From: joel:neely:fedex at: 18-Mar-2002 8:05

Hi, Charles, OK, here are my deep dark secrets... Charles wrote:
> Oh. The mystery commented portion is Perl... that makes sense, > now. Hmm... >
The point of the sig is to allow someone to discover my email address without placing it in clear text, thus making it just a little harder for spamvultures to harvest it from the plain text of the email message. The email address (string) is reversed, with the . and @ replaced with other characters. That way a spamvulturebot that is looking for strings that contain dots and at-signs would not pick up that line as an encoded email address. Here's an explanation of the sig, line by line: ; sub REBOL {}; sub head ($) {@_[0]} Semicolon is the REBOL comment prefix (thru end of line); this line contains Perl code to define: - a null function named REBOL (to ignore the header); - a function named "head" that returns its argument (this will be explained below). Since the REBOL interpreter is supposed to ignore everything above the header I didn't actually need the semicolon. I left it there as a hint, since I *do* need comment-escaped code later on. An experienced REBOL programmer would know that it wasn't needed, so that would draw attention to the question, "Why did he make that a comment?" and provide a clue about the use of language-specific commenting. REBOL [] The REBOL header, to engage the REBOL interpreter. I needed the null function "REBOL" in Perl to make this line legal in both languages. The argument is an empty block to REBOL, but is an anonymous array reference to Perl (which will silently ignore it, due to the definition of the null function). # despam: func [e] [replace replace/all e ":" "." "#" "@"] This one is a tad obscure! ;-) I need functions to fix the ./: and @/# substitutions in both languages. Each of these functions needs to be hidden from the other language (in the simplest/shortest way possible). The octothorp/hash/pound is the single-line comment prefix in Perl, just as ; is to REBOL, *but* in REBOL it marks the beginning of an ISSUE! data value (in this case, a zero-length one! ;-)
>> print #1234
1234
>> print # >> type? #
== issue!
>> length? #
== 0 REBOL silently ignores expressions or simple values which appear "between expressions" (i.e., without being used to set a word's value, as function arguments, etc...) as long as they have no side-effects. Thus I can begin the line with a comment marker to make Perl ignore this line, but it looks to REBOL like an extra trivial value that can be ignored. The rest of the line simply defines the DESPAM function to REBOL as handling the punctuation (de)substitution. ; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"} This is the Perlish version of the previous line. The semicolon hides this line from REBOL. Semicolons are used in Perl to separate statements/expressions, so this just looks to Perl like an empty expression followed by a function definition. There's one additional trick in this function; the REBOL native PRINT puts a newline at the end of what's displayed to the console. Perl doesn't do that; it let's the script decide when/where to put in line breaks. Therefore, the Perl "despam" function has to put a newline at the *beginning* of its result (since the result will be reversed before printing ;-). print head reverse despam "moc:xedef#yleen:leoj" ; Now I have all the functions I need in both Perl and REBOL; both languages have "print" and "reverse" functions, and I've defined "head" for Perl. The gimmick is that REBOL returns a reversed series at its tail, but Perl returns a reversed string at its beginning. Therefore I needed "head" for REBOL, but the Perl version didn't need to do anything. Lots of work for a five-line sig, but it was fun to get all of the puzzle pieces lined up just right... -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]