EigenCharges #
A new sleight of syntax for ya:
class RubyTalk < Filter + to("ruby-talk@ruby-lang.org") + cc("ruby-talk@ruby-lang.org") - from("common.troll@gifted.net") end class SelfBlog < Filter + to("selfblog@hobix.com") + subject("secretpassword") def process(msg) Blog.add_post(msg) end end
Young ones, see if you can figure out how it’s done before I hand you the actual raw sprinkles of meta magic dust. Specifically: (1) where are the rules getting stored? and (2) how are the operators actually implemented? Just have a think before the spoilers.
First, the Code
class Filter class Rule attr_accessor :field, :terms, :action def initialize(f, *a) @field = f @terms = a end def -@; @action = :reject end def +@; @action = :accept end end class << self attr_accessor :rules [:from, :to, :cc, :subject].each do |m| define_method(m) do |*a| r = Rule.new(m, *a) (@rules ||= []) << r r end end end end
To view the rules for mail going into the RubyTalk
mailbox:
RubyTalk.rules.each do |r| puts "[#{r.action}] if #{r.field} matches `#{r.terms}'" end
And, the Answers
1. Where are the rules getting stored? The rules are stored in instance variables inside each class. So, not in a RubyTalk
object. In the actual RubyTalk
class. Right next to the methods.
2. How are the operators actually implemented? By now, you probably can see just fine. Unary operators on the Rule
class. The to
and from
class methods create Rule
classes, which then get charged positively and negatively by the operator.
MenTaLguY
That’s beautiful.
You know, it’s a bit embarassing, but before this I had never learnt what method names went with the unary operators. I shall have to file this away…
Jon
I get this, except for:
def -@; @action = :reject end
What does the @ do? As opposed to have just “def -;”
why
The unary ops are
-@, +@, ~@, !@
Adam
Jon: I believe -@ +@ Are the unary operator method names
Jon
Ah, I see. Thanks.
MenTaLguY
why: awesome, thanks~
Ezra
It appears that !@ is not definable?
teebag
wait wait..i thought i had it but i lost it. The unary + and – methods are in the Rule class, right? So how is it possible that you can call them from Filter? (Like in your example at the top.)
MenTaLguY
teebag: The unary operators are called on the results of from(), to(), etc. which are Rule objects.
MenTaLguY
Ezra: ah, good catch. Yes, everything to do with truth in Ruby is hard-coded.
MenTaLguY
(bit-twiddling is lies. all of it.)
why
Bonus Challenge
Get the
RubyTalk
one to work like this:teebag
oooooooooooooooooo. gotit.
zenspider
!@ is not a unary operator. Unfortunately it is pure syntax.
murphy
excellent, without eval!
problem is: it produces warnings (useless use of +@ in void context.)
ko1 made a lang with this +@ trick: http://flgr.0×42.net/deobfu/1-negaposi.html
why
I’m sorry. I got that from
parse.y
, which lists the unary operators inop_tbl
. Which means:But which doesn’t actually work:
gmosx
Ooh, nice ;-)
murphy
Did I mention that that x-thing in Textile was a real bad idea?
http://flgr.0×42.net/deobfu/1-negaposi.html
murphy
I guess unary ! is parsed and converted to some rb_negate method. Same to != and !~.
murphy
NegaPosi
sorry for the spam :( I should really use the Preview. And the Textile Docu.
why
NegaPosi?
MenTaLguY
Wait a minute…
>_>
why, are you telling us that
x.intern.to_s == x
isn’t an invariant for non-empty strings?That sucks—I think almost everybody was under the erroneous impression that it was. Speaking for myself, I know I am going to have to rewrite some code not to use symbols now…
why
It’s true. In a few cases.
MenTaLguY
I guess that’s okay for many things. My little lisp interpreter’s going to suffer though.
MenTaLguY
(I wouldn’t use it personally, but according to the R5RS grammar ! and !@ are both valid identifiers.)
zenspider
huh. I knew there were a couple things like that, but I didn’t realize how bad it was. I think they should be invariant as described above, and the parser/eval should be responsible for dispatching correctly, not the other way around.
FlashHater
As I said in my unposted wink, I smell something fishy. Like a Ruby spam filter. Or something of the sort. This is too EigenSpiffy to only be something to throw arround.
pHiL
Always wondered about the unary operator def syntax. Too bad about that !@ not being definable, though. Was this a yacc limitation or something? Could it be changed in 1.9?
Kevin Ballard
Huh. I didn’t know you could use instance variables in a class directly via a meta-class. That’s actually kinda frightening.
Danno
Wait, is the | operator supposed to make it so that the latter rule’s terms are copied into the former rule or what?
Yah know, I mean, the syntax is cool and all, but, maybe it’s TOO cool, for school, you know?
As a DSL , yeah, sure, but it’s… hrmm.
Well, in any case, I expect _why’s next feat to be shoe-horning the Klingon language into a DSL for putting lids on bacon grease tubs.
why
Oh, come on, Danno. Just do the exercise. You’ll learn something neat. The pipe is an “or”.
MenTaLguY
pHiL: It’s got nothing to do with yacc at all.
Ruby’s boolean operations are all hard-coded for efficiency, not implemented via methods.
zem
unariffic!
nornagon
>> :'!(unary)' # => :"!"
caveat emptor!
Tanner Burson
That is one of the simplest, and most beautiful meta-programming hacks I’ve seen in quite a while.
why
Matz has just verified that the !@ operator isn’t callable and will likely be removed.
Danno
So here’s a start. If you want to be able to chain a bunch of |’s together, then Rule might need to keep a list of siblings with which it would like to share it’s terms.
MenTaLguY
why: Can you also ping him about whether we can eventually avoid having different strings intern to the same symbol?
Matt
So, can anyone a bit more familiar with Ruby internals tell me the reason strings like ”” are converted to : ?
Matt
Okay, I just can’t get this right. I find any way to make plus signs display at all, unless it’s only broken in the ajax-y preview… What I meant to ask is why are strings like
"+(unary)"
converted to:+@
(COLON PLUS AT -SIGN)Dave Burt
We want
to be a shortcut for
(I’m rejecting ruby-talk mail because Textile makes it hard to use plus.)
Note- to | cc(a)
means(-to) | cc(a)
. That means:C Erler
Though I wouldn’t use it since it’s ugly, here’s my solution to the challenge :
C Erler
I have seen the error of my ways and slapped it around a bit :
C Erler
I have seen the post right before mine and slapped me around a bit.
why
No, good work, C Erler. The thing is: you get it now. I’m sure Dave and Danno feel better now too. Accolades for all of you.
Comments are closed for this entry.