Mixing Our Way Out Of Instance Eval?

by why in Hackety org, Mon, 06 Oct 2008 17:36:39 GMT

The lynchpin of Ruby’s pidgins and so-called DSLs (Douchebaggery as a Second Language) is the method known as instance_eval.

From an article titled Ruby DSL Blocks:

 def self.order(&block)
   order = Order.new
   order.instance_eval(&block)
   return order.drinks
 end

And another one Implementing an internal DSL in Ruby:

 def Expectations(&block)
   Expectations::Suite.instance.instance_eval(&block)
 end

From Creating DSLs with Ruby:

 class MyDSL
   def define_parameters
     yield self
   end

   def self.load(filename)
     dsl = new
     dsl.instance_eval(File.read(filename), filename)
     dsl
   end
 end#class MyDSL

So far, so good? Most often instance_eval is used, but you’ll see module_eval, too.


Now, the reason for this.

Jim Weirich: Within the builder code blocks, any method call with an implicit object target needs to be sent to our builder. To achieve this, the code blocks are evaluated with instance_eval which changes the value of self to be the builder.

He goes on to say why this could be troubling.

This is OK until you want to call a method in the calling object. Since self is no longer the calling object, you have to explicitly provide the caller.

In Weirich’s Builder, he prefers to use plain blocks and hand you the variable.

 builder { |xm|
   xm.em("emphasized")
   xm.em { xm.b("emp & bold") }
   xm.a("A Link", "href" => "http://onestepback.org")
   xm.div { xm.br }
   xm.target("name" => "compile", "option" => "fast")
   xm.instruct!
   xm.html {
     xm.head {
       xm.title("History")
     }
     xm.body {
       xm.comment! "HI"
       xm.h1("Header")
       xm.p("paragraph")
     }
   }
 }

With instance_eval, you’d end up with:

 builder {
   em("emphasized")
   em { b("emp & bold") }
   a("A Link", "href" => "http://onestepback.org")
   div { br }
   target("name" => "compile", "option" => "fast")
   instruct!
   html {
     head {
       title("History")
     }
     body {
       comment! "HI"
       h1("Header")
       p("paragraph")
     }
   }
 }

Builder once did use instance_eval, but now offers this explanation in the docs:

The instance_eval implementation which forces self to refer to the message receiver as self is now obsolete. We now use normal block calls to execute the markup block. This means that all markup methods must now be explicitly send to the xml builder.

Rails’ routing stuff also prefers to go without instance_eval:

 ActionController::Routing::Routes.draw do |map|
   map.with_options :controller => 'blog' do |blog|
     blog.show '',  :action => 'list'
   end
   map.connect ':controller/:action/:view'
 end

By now, it probably seems like instance_eval has been driven out of play by the mature libs and now only lingers in the dabbling blog posts.


I don’t care about the best way to do this. The fact is: even “normal blocks” are prone to bugs. I had to fix up the Builder example above because it’s wrong in the docs.

 xm.em("emphasized")             # => emphasized
 xm.em { xmm.b("emp & bold") }   # => emph & bold
 xm.a("A Link", "href"=>"http://onestepback.org")
                                 # => A Link
 xm.div { br }                    # => 

There are two errors in the above example. The date on the RDoc is Sun Feb 05 23:49:01 EST 2006.


Recently I discovered another option to all of this, thanks to the work of Guy Decoux.

While investigating a library Guy never released (called prop,) I realized that perhaps he was on to something while fooling with mixins and the inheritance chain.

Think about it: instance_eval changes self, intercepts method calls and alters instance variables. Really, all we really want to do is dispatch method calls. As Jim Weirich says, changing self is the troubling side effect here.

This is a pertinent topic. Even today, ruby-core discusses a with operator and Paul Brannan chimes in:

Instance_eval for initialization has surprising behavior for instance variables (e.g. as in Ruby/Tk).

A method that affects only method calls and not instance variables would make this idiom more viable.

I don’t know whether that is a good thing or a bad thing.

Again with the good and bad.

What if there was a way to temporarily add methods for the duration of a block?

 def to_html
    Builder.capture do
      html do
       head do
         title self.friendly_title
       end
       body do
         comment! "HI"
         h1("Header")
         p("paragraph")
       end
     end
   end
 end

The essence of Builder.capture is to mixin a bunch of Builder methods, inject them into the block’s binding. This adds the html, head, comment! methods into the calling self.

Using a very small extension called mixico:

 def Builder.capture &blk
   mix_eval(self, &blk)
 end

This extension enables and disables mixins atomically. It is a single, quick operation to add and remove a module from the inheritance chain. (See the mixico README for more on this technique.)


The mix_eval method code looks like this:

 class Module
   def mix_eval mod, &blk
     blk.mixin mod
     blk.call
     blk.mixout mod
   end
 end

The mixin and mixout methods enable and disable the Module in the block’s binding.

While you might be inclined to dismiss this on the grounds of it being mixin magic, I’m starting to believe that this is a notable omission from Ruby. It’s very quick and efficient to disable and enable mixins and could prove to be a very handy technique.

Like open classes, however, I’m afraid the timidity of the business community might label it as taboo, despite it offering great flexibility to you — all of my fine, able-minded friends out there.

03

by Christian Neukirchen in Anarchaia, Fri, 03 Oct 2008 09:37:28 GMT
ThoughtThat’s it, folks. This is the last issue of Anarchaia. Life goes on at Trivium. See you all on the other side.

das ist als wuerde der ORF
aufhoeren zu senden :) — Manuel Simoni

So it’s fare thee well my own true love,
We’ll meet another day, another time.
It ain’t the leavin’
That’s a-grievin’ me
But my true love who’s bound to stay behind.
— Bob Dylan, Farewell

#haskell-blah
23:21 <FunctorSalad> lolol, loldiol, loltriol, …

A time to be born, a time to die
A time to plant, a time to reap
A time to kill, a time to heal
A time to laugh, a time to weep
— Pete Seeger, Turn! Turn! Turn!

ThoughtThanks go to: _why for making me popular, Aria for the hosting, the guys from project.ioni.st for registering and paying anarchaia.org for a year, everyone that donated for the cause, sent fan mail, or contributed links.
ThoughtAnarchaia consists of 1163 posts in a span of over 3.5 years. There were 14358 links, 2437 pictures, 1186 IRC quotes, 2180 lyrics, 410 quotes, and 232 thoughts… totalling in 20803 items, 96553 lines, 504428 words and 5.5 megabytes.

Die Stimme Gottes: “Ich habe es nicht gewollt.” — Karl Kraus, Die Letzten Tage Der Menschheit

View: 03 - More entries from Anarchaia, Hacking

02

by Christian Neukirchen in Anarchaia, Thu, 02 Oct 2008 10:05:19 GMT

He’ll take you up, he’ll bring you down,
He’ll plant your feet back firmly on the ground.
He flies so high, he swoops so low,
He knows exactly which way hes gonna go.
Timothy Leary. Timothy Leary.
— Moody Blues, Legend Of A Mind

ThoughtCreativity is the art of amazing yourself.

I see the ships of a friendly fleet
And a song so sweetly sounding
And gentle souls who think not to defeat
As across the waves they are bounding
— Gene Clark, 1975

#ruby-de
16:56 <duschendestroyer> cool
16:56 <duschendestroyer> heute ist quasi-freitag
18:14 <christophsturm> wir sagen donnerstag dazu
View: 02 - More entries from Anarchaia, Hacking

01

by Christian Neukirchen in Anarchaia, Wed, 01 Oct 2008 10:11:41 GMT

Now you’re telling me you’re not nostalgic
Then give me another word for it
You who are so good with words
And at keeping things vague
— Joan Baez, Diamonds And Rust

Well, I want you to know, I just had to go.
I want you to know, we just had to grow.
So it’s goodbye first love, and I hope you’re fine.
— The Incredible String Band, First Girl I Loved

View: 01 - More entries from Anarchaia, Hacking

30

by Christian Neukirchen in Anarchaia, Tue, 30 Sep 2008 10:16:57 GMT

Who holds the blank thoughts of people when nothing is said?
And who turns the lights out after you’ve gotten in bed?
I guess I’ll never know why
I’ll just lay here and decay here
— Moby Grape, Lazy Me

But you tell me
Over and over and over again, my friend
Ah, you don’t believe
We’re on the eve
of destruction.
— Barry McGuire, Eve Of Destruction

View: 30 - More entries from Anarchaia, Hacking

29

by Christian Neukirchen in Anarchaia, Mon, 29 Sep 2008 09:13:26 GMT

I’ll go through life searchin’
Tryin’ to find the one
I’d go slip, slip, you’d
go slip, slip away
— Love, A Message to Pretty

Court martial, court martial, then quickly was got
And the sentence passed upon me, that I was to be shot
May the Lord have mercy on them for their sad cruelty
For now the Queen’s duty lies heavy on me
— Fairport Convention, The Deserter

View: 29 - More entries from Anarchaia, Hacking

28

by Christian Neukirchen in Anarchaia, Sun, 28 Sep 2008 09:31:38 GMT

Taxman, rentman, they all chase me,
I ain’t home when they come round.
Got no money, live my life free,
That’s the best way, I have found.
— The Yardbirds, I Can’t Make Your Way

And you singing the song thinking this is the life
And you wake up in the morning and your head feels twice the sizxe
Where you gonna go, where you gonna go, where you gonna sleep tonight?
— Amy MacDonald, This Is The Life

View: 28 - More entries from Anarchaia, Hacking

Textarea Resize And Curly Quotes For Conkeror

by why in Hackety org, Sat, 27 Sep 2008 22:29:42 GMT

People say Google Chrome is a step behind Firefox because Firefox has addons. Well, excuse me, but Firefox was already a step behind Conkeror and Vimperator! Making Google Chrome a whopping TWO steps behind. (But I’m sure we’re all another full step behind some completely obscure browser which only runs on Plan 9 and is being ported to the Erlang VM.)

Here are a few Conkeror hacks that can be easily dropped into your ~/.conkerorrc. (If you need a introduction to Conkeror, see Conkeror Comes Unstuck.)


 function resize_textarea_up(field) {
   var h = field.offsetHeight;
   if (h > 120)
     field.style.height = (h - 60)   "px";
 }
 function resize_textarea_down(field) {
   field.style.height = (parseInt(field.offsetHeight)   60)   "px";
 }
 interactive(
   "resize-textarea-up",
   "Resize a textarea to be smaller.",
   function (I) call_on_focused_field(I, resize_textarea_up)
 );
 interactive(
   "resize-textarea-down",
   "Resize a textarea to be taller.",
   function (I) call_on_focused_field(I, resize_textarea_down)
 );
 define_key(content_buffer_textarea_keymap, "C-up", "resize-textarea-up", $category = "Movement");
 define_key(content_buffer_textarea_keymap, "C-down", "resize-textarea-down", $category = "Movement");

This one enables Ctrl-Up and Ctrl-Down inside a textarea. So you can stretch the box without reaching for the mouse. How about that!


 var quotes = [["squote", "C-quote", "2018"],
 ["apostrophe", "M-quote", "2019"],
 ["lquote", "C-S-quote", "201c"],
 ["rquote", "M-S-quote", "201d"],
 ["emdash", "M--", "2014"],
 ["ellipsis", "M-.", "2026"]];
for (var i in quotes) {
  var q = quotes[i];
  eval("function curly_"   q[0]   "(field) { modify_region(field, function(str) \"\\u"   q[2]   "\" ); }");
  interactive(
    "curly-"   q[0],
    "Inserts a curly "   q[0]   " at the cursor in a textarea.",
    eval("function (I) call_on_focused_field(I, curly_"   q[0]   ")")
  );
  define_key(content_buffer_text_keymap, q[1], "curly-"   q[0], $category = "Editing");
}

I find myself using more UTF-8 characters that aren’t on the keyboard. Like these are four keybindings for curly quotes.

If you hit the Ctrl key and the single- or double-quote key, you’ll get a left-side curl. An Alt gives a right-side curl. There are a few dashes in there, too. This stuff could be done in the keymaps, but I wanted to see how it could be scripted. OS X already has keymaps for these I think.


One other thing. If you are in a textarea and you hit Ctrl-I, it’ll open the textarea in an external editor. For some reason, vim wasn’t doing it for me. Well, I had the setting wrong.

 define_variable("editor_shell_command", "gvim -f");

Lastly, if you’re using a site that has its own keybindings (such as Try Ruby,) you can use Ctrl-Alt-Q to let all keystrokes pass through. Hit Esc to give focus back to the browser.

26

by Christian Neukirchen in Anarchaia, Fri, 26 Sep 2008 07:54:39 GMT
ThoughtNo Anarchaia tomorrow, I’m going to the Oktoberfest.

Crowds of people standing everywhere
‘Cross the street I’m at this laugh affair
And here they always play my songs
And me, I wonder if it’s…
— Love, Maybe The People Would Be The Times Or Between Clark And Hilldale

Every morning I would see her waiting at the stop
Sometimes she’d shop and she would show me what she bought
All the people stared as if we were both quite insane
Someday my name and hers are going to be the same
— The Hollies, Bus Stop

View: 26 - More entries from Anarchaia, Hacking

25

by Christian Neukirchen in Anarchaia, Thu, 25 Sep 2008 11:38:01 GMT

All the things that I’m a-sayin’ an’ a-many times more.
I’m a-singin’ you the song, but I can’t sing enough,
‘Cause there’s not many men that done the things that you’ve done.
— Bob Dylan, Song To Woody

Yeah, said its all right
I wont forget
All the times Ive waited patiently for you
And youll do just what you choose to do
And I will be alone again tonight my dear
— Love, Alone Again Or

View: 25 - More entries from Anarchaia, Hacking

A Legend Never To Be Solved

by why in Hackety org, Thu, 25 Sep 2008 06:33:52 GMT

I don’t mean to be overly sentimental or maudlin. Guy Decoux (pronounced ghee de-coo, I believe) was a great secret among Ruby enthusiasts. I am sad to hear that he is gone. I dropped my glass the minute I heard. He was fantastic. Of his legend I will always tell. He leaves us much to think about.

He was around long before I happened upon Ruby and, man, the guy was sensationally smart. He knew Ruby inside and out. Really, he was fantastic with Ruby internals. I’m happy to have long employed some of his cunning code in Shoes: the ts_each and ts_funcall2 in shoes/ruby.c. He only made 19 commits to Ruby in the years 2000 to 2003, but he discovered countless bugs and you can find his ruby-core messages cited often in the ChangeLog.


He was probably the earliest master of Ruby outside Japan. He began study of Ruby in 1999 (ruby-talk:859) and was right there at the inception of ruby-core (ruby-core:27.) Matz will be unhappy to hear of this news, since Guy had been so helpful over these last nine years.

He was few on words, but not necessarily because he was poor at English. I asked him for some pointers, long ago, when I started work on Try Ruby. He sent back a reply that not only detailed a number of bugs he discovered, but also a postscript asking me to fix the reverse DNS for my e-mail address, attaching some lines from his mail log as proof!

There I was, quite surprised to see actual words and paragraphs in his e-mail. The real ts! He rarely gave color commentary on his code. He gave only transcripts of his conversations at the shell prompt with his machine called pigeon. (In previous years, sometimes it had been svg.) I thought it was funny that his transcripts always ended with a blank shell line pigeon%, as if he parked it there for you, awaiting further command. And that was part of the marvel of ts: he respected your smarts to figure out his code and he let his code entirely represent him.

You’ll hear a lot of people say that we didn’t know who he was. That no one met him. But we all read alot of his code. And clearly that was how he wanted us to know him. Think of how that stands in such sharp contrast to the self-advertisement and vanity journalism of the Web today. We knew him, just not in the way we’re used to.


The RubyFrance blog has this photo of Guy:

Anyway, if the real pigeon is intact, I hope it will find its way into a wing of the Matz Museum, alongside the Perl CGI book that Matz inherited from his dad and the magnetic tapes in Matz’ closet. (Ruby pre-1.0 is lost somewhere in there on outdated media.)


Here is the very thoughtful eulogy given by Jean-François Trân. You can give your thanks to @underflow_ for writing it.

I am archiving it here, though the original is on ruby-talk. I would be very interested to hear memories from matz or David Alan Black or anyone who had correspondence with Guy. It would be great to revisit some of his finer replies over the next few days, wouldn’t it?

I’m sad to announce you Guy Decoux’s death in the beginning of the month of July 20008. He was 53 years old. He died accidentally, intoxicated by the smokes of the fire that took place during the night in his flat in Louveciennes (near Paris).

Guy Decoux was network and system admin at the Plant Genomics Research Unit of INRA (Agricultural Research labs, where he worked since 1982) in Moulon’s Farm (Moulon’s plateau, in the south west of Paris).

He was an Internet pioneer. For example, he worked on Oraplex, one of the first Oracle to web gateways. He deployed the first website that gave access to an ACeDB system by the end of 1993. He had worked on bioinformatic free software, like ProticDB, a plant proteomic database.

He was part of the generation of developers who switched from Perl to Ruby in the 90s. While his mastering of Perl was already great, his knowledge about Ruby was so deep and impressive that a lot of Rubyists would have been very happy to have the same one. Guy contributed to Dave Thomas’ book, “Programming Ruby”. Of course he polled for the comp.lang.ruby and fr.comp.lang.ruby newsgroups creation. He was maintaining some libraries like PL/Ruby a procedural language for PostgreSQL, bdb / bdb1 bindings for Berkeley DB, bz2 bindings the libbzip2 compression library and MMap class, a class for Memory-mapped files.

To my knowledge, he was the only french person to have commits right to Ruby MRI source code. I don’t know if he was officially member of the Ruby Core Team (I don’t know if there is an official Ruby Core Team list).

I’m not sure ‘ts’ (what does ‘ts’ mean in his electronic address?) had ever been to RubyConf nor any Ruby conference. Well I don’t know if there is a french Rubyist who ever meet him. Was he mysterious or secret ? Maybe he was just reserved. His colleagues described Guy as reserved, kind, available, professional and technically very competent. His messages on Ruby-Core or Ruby-Talk, sometimes with a bit of humor, show all that.

This is a loss for Ruby Community.

In the name of french association RubyFrance, I present my condolences to Guy Decoux’s family, his friends and his collegues.

Update: Matz has replied:

I was socked. He was one of the smartest guy among our community. Even thought I haven’t had a chance to meet him in person, he had been a great source of knowledge and insight. I should have exchanged ideas with him more often. I miss him.

View: A Legend Never To Be Solved - More entries from Hackety org, Hacking

24

by Christian Neukirchen in Anarchaia, Wed, 24 Sep 2008 17:02:24 GMT

She may beg she may plead
She may argue with her logic
And then mention all the things I’ll lose
That really have no value
In the end she will surely know
I wasn’t born to follow
— Carol King and Gerry Goffin, Wasn’t Born To Follow

The river flows
It flows to the sea
Wherever that river goes
That’s where I want to be
— Roger McGuinn, Ballad Of Easy Rider

View: 24 - More entries from Anarchaia, Hacking

17

by Christian Neukirchen in Anarchaia, Wed, 17 Sep 2008 09:22:54 GMT
ThoughtI’m moving. Anarchaia will resume publishing at least Thursday, September 25.

I need my privacy, I lead a secret life
Sleep with the enemy, and betray both sides
I travelled all my life, but never got away
From the killing jar, and it got me sick
— Black Box Recorder, England Made Me

Do you believe in love at first sight?
Do you believe in fate?
I believe the good things
Only come to those who wait
We’ve got to plan the journey
Eliminate all mistakes
Take the safe route
It’s called the art of driving
— Black Box Recorder, The Art Of Driving

View: 17 - More entries from Anarchaia, Hacking

16

by Christian Neukirchen in Anarchaia, Tue, 16 Sep 2008 09:52:11 GMT
by LdDH

Welcome to the House of Lies
For you and I it’s like paradise
You can do what you wanna
When you do, I’ll act like I’m surprised
— The Shortwave Set, House Of Lies

I typed OMG, should be you and me
You wrote LOL, wrote LOL
My browser froze right down to my toes,
I said go to hell.
— The Hot Toddies, HTML

View: 16 - More entries from Anarchaia, Hacking

15

by Christian Neukirchen in Anarchaia, Mon, 15 Sep 2008 09:25:06 GMT

When you lie in the desert sun
believe me, you make it so much fun
I know you’re coming back
and I’ll wait, I’ll wait forever
— Tiger Trap, Chester

I don’t wanna know
This Love
I don’t wanna know
It’s all I’ll ever have
This love
I don’t wanna know
— The Magic Numbers, This Love

View: 15 - More entries from Anarchaia, Hacking

 

Hacking

Great ideas for hackers, interesting solutions to problems, geeky stuff

Feeds