Saturday, October 18, 2008

"Fun" with Hook Methods in Ruby

I've been wrestling with what turned out to be a rather interesting issue involving ruby hook methods. I don't yet have a solution to the problem but perhaps the activity of describing the problem in writing will illuminate a solution. Hook methods in ruby are callback methods you can implement in your code to get notified at interesting points in the lifecycle of a ruby object. The one which caused trouble in my case is inherited. By implementing the inherited method in a class you can get called back when another class inherits from it. It's quite useful when you want to do something like record each descendant of a given class, for example.

I ran into an issue with inherited while trying to understand a very strange behaviour in my IDE of choice, NetBeans. When running my rails test cases from NetBeans, I noticed they were not transactional, but when run on the command line they were. After sending a flame-o-gram which I will soon need to retract to the nb ruby mailing list, I decided to poke around in their code. I finally narrowed the problem down to their testrunner code.

In the newest version of NetBeans they have added a nicer ruby testrunner. In order to provide some features this new testrunner keeps track of all descendants of Test::Unit::TestCase. It does this, by, you guessed it, using the inherited method. When I delved into this code the first problem I saw was pretty obvious. The author had violated what I will now credit my friend Jim by referring to as Weirich's Hook Method Implementation Commandment:

Thou Shalt Always Delegate to the Previous Implementation

The reason this is important is that when you implement a hook method, you can easily step on someone else who had implemented it for another reason. Using the rails alias_method_chain will normally take care of this for you, but because this code loads before rails they didn't have that option and had not done the right thing and delegated explicitly.

And sure enough, I noticed that when I commented out the inherited method in the testrunner my tests became transactional. I figured at this point I had it licked. I went ahead and changed the NB testrunner code to delegate correctly and tried again. Sadly, it had no affect on the transactional issue. Much head scratching ensued. After many hours of investigation, I finally tracked down the real problem. I noticed that the use_transactional_fixtures class attribute of Test::Unit::TestCase was not being set. This led me to investigate how class_inheritable_attributes works in rails. Eventually I was able to put together a failing test case which expresses the problem. Here it is:

require File.dirname(__FILE__) + '/inheritable_accessor'
require File.dirname(__FILE__) + '/../test_helper'

class A
class_inheritable_accessor :foo
self.foo = "bar"
end

class B < A

end

class InheritableAttributesTest < Test::Unit::TestCase

def test_foo
assert_equal "bar", B.foo
end
end


And here what's in inheritable_accessor.rb:

class A
class << self
alias_method :a_old_inherited, :inherited

def inherited(base)
puts "A inherited"
a_old_inherited(base)
end
end
end

To try this at home, simply make a new rails project and drop these two files into your test/units directory. It should fail. But why? The inherited method does delegates to the previous implementation correctly, right? Now try switching the order of those two require statements. Poof, it passes.

Turns out the problem happens because of how class_inheritable_accessor is implemented. As you probably have guessed, it uses inherited. And yes, it does correctly delegate to the previous implementation. But it's where its implemented that is the problem: in order to let all classes be able to use this method, it's implemented on Class. However, there is an unfortunate side effect to this decision: it breaks for any class loaded before this code which itself defines inherited. In our example, the A class defines the inherited method before the rails code is loaded. But since the A class extends the Class class it's definition of inherited overrides the version rails adds to Class. The net outcome is that for the A class, and any class loaded before rails that defines inherited, class_inheritable_accessor is broken.

What's the right way to fix this? I'm not honestly sure. It could be that in order to do something like this which effectively adds a feature to the language, you need to be loaded first. On the flip side, it could be considered a bug that class_inheritable_accessor is broken in cases like this. Well, I had hoped that by the time I got this point in the post a clear solution would emerge. I suppose I'll have to leave it, as they say, as an exercise for the reader :)

Update: I was about to post this, and I went to grab some dinner and finally realized the solution: A still does not entirely obey Weirich's law. It correctly delegates to a previous implementation in the same class, but not to the superclass. A call to super at the end of the inherited method causes the test to pass. Adding the super call to the NB test runner code also causes my tests to be transactional again. Yay!

25 comments:

samael said...
This comment has been removed by the author.
Erno said...

Very interesting indeed -- great post, thanks a bunch for solving the problem!

111 said...

WoW shares many wow gold of its features with previously launched games. Essentially, you battle with Cheapest wow gold monsters and traverse the countryside, by yourself or as a buy cheap wow gold team, find challenging tasks, and go on to higher Cheap Wow Gold levels as you gain skill and experience. In the course of your journey, you will be gaining new powers that are increased as your skill rating goes up. All the same, in terms of its features and quality, that is a ture stroy for this.WoW is far ahead of all other games of the genre the wow power leveling game undoubtedly is in a league of its own and cheapest wow gold playing it is another experience altogether.
Even though WoW is a wow gold cheap rather complicated game, the controls and interface are done in buy warhammer gold such a way that you don't feel the complexity. A good feature of the game is that it buy wow items does not put off people with lengthy manuals. The instructions cannot be simpler and the pop up tips can help you start playing the game World Of Warcraft Gold immediately. If on the other hand, you need a detailed manual, the instructions are there for you to access. Buy wow gold in this site,good for you ,WoW Gold, BUY WOW GOLD.

cheap wow gold said...

It was not long cheap wow goldbefore some one knocked atwow gold cheap wow gold for salethe house-door and called, open the door, dear children, your mother is here, and has brought something back with her for each of you. But the little wow8goldkids knew that it was the wolf, by the rough voice. We will gold4power not open the door, cried they, you are not our mother. She has a soft, pleasant voice, but your voice is rough, you are the wolf.

Then the wolf went World Of Warcraft Goldaway to a shopkeeper and bought himself a great cheapest wow goldlump of chalk, ate this and made mmogap his voice soft with it. The he came back, knocked at the door of the house, and igsky called, open the door, dear children, your mother is here and Cheapest Wow Goldhas brought something back with her for each of you.

wow gold said...

Weekends to peopleig2tmean that they can have a two-day wowgold4europe good rest. For example, people gameusdcan go out to enjoy themselves or get meinwowgoldtogether with relatives and friends to talk with each storeingameother or watch interesting video tapes with the speebiewhole family.
Everyone spends agamegoldweekends in his ownmmoflyway. Within two days,some people can relax themselves by listening to music, reading novels,or watchingogeworld films. Others perhaps are more active by playing basketball,wimming ormmorpgvipdancing. Different people have different gamesavorrelaxations.
I often spend weekends withoggsalemy family or my friends. Sometimes my parents take me on a visit to their old friends. Sometimesgamersell I go to the library to study or borrow some books tommovirtexgain much knowledge. I also go to see various exhibition to broadenrpg tradermy vision. An excursion to seashore or mountain resorts is my favorite way of spending weekends. Weekends are always enjoyable for me.
igxe swagvaultoforu wowgold-usaignmax wowgoldlivebrogame thsaleGoldRockU

琪琪 said...

you are not our mother. She has a soft, pleasant voice, but your voice is rough, you

are the wolf.
...................................................
......

琪琪 said...

who has started the last 12 games in the absence of Yi Jianlian. "I know I've improved

a ton defensively this season."
...................................................
.......

琪琪 said...

If on the other hand, you need a detailed manual, the instructions are there for you to

access.
...........................................................
...

beauty said...

. . . .
. . . . . . .
. . . . . .
. . . . . . . . . .
. . . . . . . . . . . . . . . . .
This article is very good,I like it !

beauty said...

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . good,very good!

beauty said...

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I like it

Nguyen Manh said...

池袋 風俗
渋谷 風俗
新宿 風俗
コンドーム 激安
アダルトDVD
av 写真
大人のおもちゃ
おとなのおもちゃ
アダルト ブルーレイ
アダルトショップ
ペニス増大
電マ
TENGA
SM 通販
メンズセクシー下着
男性用下着
メンズTバック
大規模修繕
決済代行
SEO
SEO
Grid geat grop
カード決済
ブライダルエステ
FX 外国為替
クレジットカード 比較
仔犬
子ウサギ
仔ウサギ
アダルトショップ
アダルトグッツ
ゴールドカード年会費
浮気調査 探偵
身辺調査 探偵

Nguyen Manh said...

企業調査 探偵
盗聴発見 探偵
特殊調査 探偵
妻の浮気 夫の浮気
尾行調査
企業調査
所在調査
身辺調査
追跡調査
素行調査
追跡調査
信用調査
身上調査
所在調査
妻の浮気 相談
素行調査 相談
身元調査 相談
離婚 相談
追跡調査 相談
ストーカー対策 相談
結婚詐欺 相談
オナホール
メール 英文
ビジネススクール 英語

Adi said...

Oes Tsetnoc one of the ways in which we can learn seo besides Mengembalikan Jati Diri Bangsa. By participating in the Oes Tsetnoc or Mengembalikan Jati Diri Bangsa we can improve our seo skills. To find more information about Oest Tsetnoc please visit my Oes Tsetnoc pages. And to find more information about Mengembalikan Jati Diri Bangsa please visit my Mengembalikan Jati Diri Bangsa pages. Thank you So much.
Oes Tsetnoc | Semangat Mengembalikan Jati Diri Bangsa

donghua said...

Your blog is very good, it's the best blog I've ever seen, thank you!
By the way, do you like polo shirts, which are very chic, especially the polo t shirts, I love them very much. I also like playing tennis rackets, it can keep healthy, what do you like to do?
polo t shirts women
polo t shirts on sale
polo t shirts for women
polo shirts on sale
polo shirts men
men's polo shirt
men polo shirt
mens polo shirts
mens polo shirt
cheap polo shirts
discount polo shirts
men's polo shirts
women's polo shirts
cheap tennis racket
discount tennis racket
prince tennis racquet
head tennis rackets
wilson tennis racket
babolat tennis racquet

Edwin said...

Buy Kamagra
Earn Google
Viagra Cialis
Cheap Kamagra
Cheap Viagra
Cheap Cialis
Make Money on Google
M65 Jacket
M65 Field Jacket
Airline Dog Carrier
Airline Dog Carriers
Viagra Cialis
Earn Google
Airline Dog Carrier
Airline Dog Carriers
Airline Approved Dog Carriers
ED Hardy Wholesale
Copy DVD Software
How to Send Fax
14k Yellow Gold
Redneck Costume
14k Gold Heart
Tandem Baby Stroller

guli said...

I come across your blog when I surf the net, and after I read your articles, I love your blog deeply.
Are you a fashion chaser? And have you tried men polo shirt, which are very beautiful, especially the mens polo shirts, I love them very much.
So glad to introduce us as the outlet of
mens polo shirt
women's polo shirts
men's polo shirts
which are popular among the customers, and we also recommend
womens polo shirt
polo shirts women
polo shirts for women
and these products are deserved to be looked at
polo shirts men
polo mens shirt
polo women shirts
men's polo shirt

maxell said...

I always wanted to write in my site something like that.
phentermine without prescription loose weight
phentermine 37.5 without prescription 56
phentermine 37.5 no prescription medicals
phentermine 37.5 mg medicine
phentermine 37.5mg pharmacy
phentermine 37 5 healthy weight
phentermine 37.5 fat
anxiety medication anti.
phentermine 37.5 meds
phentermine 37.5 mg no prescription womens

john said...

http://georgeseal.yolasite.com
http://benhasse.vox.com
http://vedegene.livejournal.com
aser de dertyo lolas
qaw frta huna ser taye re
http://johndic.biz.ly/cgi-bin/blog
http://georgemaz.blog.com
http://mavitrain.bravehost.com

maxell said...

Quick Weightloss
wellness troubles
My Fitness
Dieting
Obesity
Good Health
Obese Women
Fatness
slimming down
Healthy Body

aiya said...

Office 2010is powerful!
Microsoft Office 2010is the best software in the world.
Microsoft wordis so great!
Office 2007makes life great!
Many people likeMicrosoft Office.
Microsoft Office 2007is welcomed by the whole world.
Office 2007 keyis available here.
Office 2007 downloadis on sale now!
Office 2007 Professionalbring me so much convenience.
Outlook 2010 make life wonderful!
Microsoft outlook is my love.
Microsoft outlook 2010 is convenient!
Windows 7 is convenient!

teramoney said...

http://www.tera2u.com/news/detial/The-role-of-tera-class-up-to-58

http://www.wowbotsfree.com/some-current-popular-ways-of-online-games-charging/

http://www.dnfonlines.com/a-classification-of-online-games-charging/

xinag zhong said...

Amazing submit. We've knowledgeable all of these highs and lowsCheap wow gold regarding matching me. Inside correct circumstance, We entirely consider coupling is the foremost way to go, yet I have likewise believed for most of experiencing to pair gets hotter has not been proper (for virtually every in the explanations an individual mentioned) so itBuy rs gold needs to be taken on stability.

AntoL-Nyo said...

HD kaliteli porno izle ve boşal.
Bayan porno izleme sitesi.
Bedava ve ücretsiz porno izle size gelsin.
Liseli kızların ve Türbanlı ateşli hatunların sikiş filmlerini izle.
Siyah karanlık odada porno yapan evli çift.
harika Duvar Kağıtları bunlar
tamamen ithal duvar kağıdı olanlar var

AntoL-Nyo said...

Ben istanbuldan selda 22 yaşında konfeksiyon içşisiyim Amatör Porno sizleri bekletmeden hemen hikayeme geçiyorum.. Biz 5 katlı bir binanın en üst katında yaşıyorduk ve bir öğlen paydosunda sevgilim beni Anal Sikiş aradı evdeydim çünkü evle iş yerim arasında 2 dakika bile yoktu.. Bende Asyalı Porno sevgilime benden telefon beklemesini söyledikten sonra evin durumuna baktım evde kardeşlerim ve annemin Esmer Porno birkaçtane arkadaşı vardı bu iş imkansızdı tekrardan düşündüm ve çatı katı aklıma geldi sevgilime telefon açıp çatıya çıkmasını ve Fantazi Porno beni beklemesini söyledikten sonra telefonu bir süre elime almadım anneme işe gidiyorum dedikten sonra Gay Porno hemen üst kata çatıya çıkıp sevgilimin
dudaklarına yumuldum az bir süremiz Götten Sikiş vardı ve çok istiyordum onu hemen önünde diz çöküp sikini çıkardım kocaman olmuştu bile... Özlemişti beni HD Porno bitanem başladım sikini yalamaya kafasını öpüyor onu çıldırtıyordum sevgilim saçlarımdan tutmuş ağzımı keyifle sikerken çatı katının kapısı açıldı toparlanamadan Lezbiyen Porno komşunun şişman oğlu efecan gelmişti ben dizlerimin üzerinde sevgilimin Liseli Porno siki ağzımda yakalanmıştım hemen bu halimizi gören komşu oğlu Sarışın Sikiş kaçarcasına gitti.. Sevgilim bir süre güldükten Türbanlı Porno sonra bu şişko neden kaçtı korktu herhalde onu sikicem sandı galiba dedikten sonra bir kahkaha daha attı ben sevgilimin Türk Porno sikine deli gibi saldırıyor yalıyor emiyordum boşalmasını istiyor Zenci Porno sütünü içmek istiyordum sevgilim ağzımı sike sike boşaldı hepsini yuttum bir damlasını ziyan Porno etmedim ve sevgilimle vedalaşıp ayrıldık... Ben her defasında sikiş yapmadan önce yazporno diye olan türkçe siteden Porno izle bölümüne girip seyrediyorum azdıktan sonra şahane sikiş ile gözleri kamaştırıyorum.