Hello and welcome to the restorm technical blog. It is here that we post about what is happening in our labs, what keeps us busy and why X doesn't work. Read more about us on the about page.
ARMIT - Jumping the git train
I want to be on it. So I release armit to the world – even before its all mature (the way we like our beer). What’s armit, you say? Well, Armit is ‘ActiveRecord Multiple InheriTance’. Ok, that’s contrived you say, right. But it rings well.
With armit you can finally do all that crazy table stuff you’ve always wanted to. I promise to write more about it here – and to make a formal release once it is ready. Birdie, fly:
http://github.com/kschiess/armit/tree/master
git://github.com/kschiess/armit.git
Meanwhile, back at the ranch … that new kid git really rocks me off of my feet. And github looks really promising – so promising in fact that we might host more projects there in the future (not affiliated). Do give it a whirl!
Edit: Now that I read through it, that post reads like the spam I am getting. The same giddy excitement over not much. That’s a mood I am in often, I call it taking pleasure in living.
yours truly, kaspar
eliminate, stamp out and abolish redundancy - to hell with spec/mocks
We firmly believe a testing framework should not also bring a mocking framework along. And we choose flexmock over the alternatives. Also – that choice was made before switching to rspec, so we weren’t at all happy with spec/mocks and flexmock battling themselves in our code.
The battle was inevitable, since both offer you convenience methods like
object.should_receive(:message)
Are you sure which framework you use in your rails specs? Really? Read on.
Ripping out spec/mocks
So you rip it out, right? No. Even though rspec allows you to configure mocking, rspec_on_rails will load and use the spec/mocks framework.
We selfishly rewrote rspec_on_rails into rspec_flexmock_on_rails. Branching is not always a good idea, but this time – it might just solve things for some people, that’s why we put our code in public under the same license that rspec is. Here goes:
http://swissrb.rubyforge.org/svn/rspec_flexmock_on_rails/
Please leave us a comment – if enough people start using this, we might be tempted to patch…
yours truly, kaspar
Tending to the blog and other crazy stuff
Let’s assume you want to call #capture(&block) somewhere out of view context. Like so (caution, haml ahead):
= form.radio_button_group_with_label 'How\'s the surf?' do |button|
= button.create 'IE 6'
= button.create 'IE 7'
= button.create 'A real Browser'
Let’s look at how we might do this:
def radio_button_group(label, field, &block)
builder = RadioButtonGroup.new(self, field)
label_tag = content_tag('label', label)
content_tag = ''
proc {
content_tag = capture(builder, &block)
}.bind(eval('self', block.binding)).call
return label_format(
label_tag,
content_tag
)
end
If you look beside the boilerplate that is for formatting and other irrelevant stuff (coder attitude forever!), you see a central snippet that has a bizarre beauty about its airs:
proc {
content_tag = capture(builder, &block)
}.bind(eval('self', block.binding)).call
We create a block using #proc, #bind something to it (as a new execution context) and then #call it. So far.. so good. This executes the block in the content of the view, which is needed for easy #capture access. Now what is the #eval(...) about? Well, turns out that Proc#bind() will only accept an object instance as an argument, no binding. Even though that would be logical, would it not?
So admire the thing in all its hideousness – and see the equivalence to
eval('self', block.binding).instance_eval do
# ...
end
Or, using facets
block.binding.self.instance_eval do
# ...
end
Let’s assume for a second that Proc#bind would take a binding as argument. How would that transform the piece?
proc do
# ...
end.bind(block.binding).call
A lot cleaner already. Here’s the piece of magic that allows you to do that:
class Proc
def bind_correct(self_or_binding)
if self_or_binding.kind_of? Binding
bind_incorrect eval('self', self_or_binding)
else
bind_incorrect self_or_binding
end
end
alias :bind_incorrect :bind
alias :bind :bind_correct
end
As always, have fun. The interested reader should take a look at the implementation of Proc#bind in active_support. Clever, that.
yours truly, kaspar