chris blogs: January 2007

31jan2007 · Halbjahreszeugnis 13/1

Halbjährlich und aus Gründen der Vollständigkeit folgt nun mein (letztes echtes) Zeugnis von 13/1:

Zeugnis des Gymnasiums 2006/2007 13/1
Sprachlich-literarisch-künstlerisches Aufgabenfeld
Deutschgut12
Englischsehr gut13
Bildende Kunstgut11
Gesellschaftswissenschaftliches Aufgabenfeld
Geschichte/Erdkundegut12
Ethikbefriedigend9
Mathematisch-naturwissenschaftliches Aufgabenfeld
Mathematikgut11
Chemiegut10
Biologiesehr gut13
Sportgut10
Durchschnitt1.88911.222

Dieses Jahr also wieder ein bisschen besser als letztes (1.889 gegenüber 2.0), und zum seit sehr langer Zeit mal “Gut” in Sport. ;-)

Meine Abi-Note nur aus den jetzigen Punkten wäre 3.3, läuft das nächste Halbjahr genau so, hätte ich schon 2.7 ohne eine einzige Abitursprüfung. Da lässt sich doch was machen…

NP: Bright Eyes—Ship In A Bottle

24jan2007 · Announcing test/spec 0.3, a BDD interface for Test::Unit

Today I’m releasing test/spec 0.3, a library to do BDD with Test::Unit.

(See below for changes in version 0.3.)

What is test/spec?

test/spec layers an RSpec-inspired interface on top of Test::Unit, so you can mix TDD and BDD (Behavior-Driven Development).

test/spec is a clean-room implementation that maps most kinds of Test::Unit assertions to a ‘should’-like syntax.

Consider this Test::Unit test case:

class TestFoo < Test::Unit::TestCase
  def test_should_bar
    assert_equal 5, 2 + 3
  end
end

In test/spec, it looks like this:

require 'test/spec'

context "Foo" do
  specify "should bar" do
    (2 + 3).should.equal 5
  end
end

test/spec does not include a mocking/stubbing-framework; use whichever you like to—FlexMock and Mocha have been tested.

test/spec has no dependencies outside Ruby 1.8.

Mixing test/spec and test/unit

test/spec and Test::Unit contexts/test cases can be intermixed freely, run in the same test and live in the same files. You can just add them to your Rake::TestTask, too. test/spec allows you to leverage your full existing Test::Unit infrastructure.

test/spec does not change Test::Unit with the exception of monkey-patching Test::Unit::TestSuite to order the test cases before running them. (This should not do any harm, but if you know a way around it, please tell me.)

Wrapped assertions

  • assert_equal: should.equal, should ==
  • assert_not_equal: should.not.equal, should.not ==
  • assert_same: should.be
  • assert_not_same: should.not.be
  • assert_nil: should.be.nil
  • assert_not_nil: should.not.be.nil
  • assert_in_delta: should.be.close
  • assert_match: should.match, should =~
  • assert_no_match: should.not.match, should.not =~
  • assert_instance_of: should.be.an.instance_of
  • assert_kind_of: should.be.a.kind_of
  • assert_respond_to: should.respond_to
  • assert_raise: should.raise
  • assert_nothing_raised: should.not.raise
  • assert_throws: should.throw
  • assert_nothing_thrown: should.not.throw
  • assert_block: should.satisfy

Additional assertions

These assertions are not included in Test::Unit, but have been added to test/spec for convenience:

  • should.not.satisfy
  • a.should.predicate (works like assert a.predicate?)
  • a.should.be operator (where operator is <, <=, >, >=, or ===)
  • should.output, to check what is printed

Messaging/Blaming

With more complex assertions, it may be helpful to provide a message to show if the assertion has failed. This can be done with the Should#blaming or Should#messaging methods:

RUBY_VERSION.should.messaging("Ruby too old.").be > "1.8.4"

(1 + 1).should.blaming("weird math").not.equal 11

Custom shoulds (“Matchers”)

To capture recurring patterns in parts of your specifications, you can define custom “shoulds” (RSpec calls them “matchers”) in your contexts, or include modules of them:

context "Numbers"
  class EqualString < Test::Spec::CustomShould
    def matches?(other)
      object == other.to_s
    end
  end

  def equal_string(str)
    EqualString.new(str)
  end

  specify "should have to_s"
    42.should equal_string("42")
  end
end

Alternatively, your implementation can define CustomShould#assumptions, where you can use test/spec assertions instead of Boolean predicates:

class EqualString < Test::Spec::CustomShould
  def assumptions(other)
    object.should.equal other.to_s
  end
end

A CustomShould by default takes one argument, which is placed in self.object for your convenience.

You can CustomShould#failure_message to provide a better error message.

SpecDox and RDox

test/spec adds two additional test runners to Test::Unit, based on the console runner but with a different output format.

SpecDox, run with --runner=specdox (or -rs) looks like RSpec’s output:

spec.output
- works for print
- works for puts
- works with readline

RDox, run with --runner=rdox (or -rr) can be included for RDoc documentation:

== spec.output
* works for print
* works for puts
* works with readline

SpecDox and RDox work for Test::Unit too:

$ ruby -r test/spec test/testunit/test_testresult.rb -rs

Test::Unit::TC_TestResult
- fault notification
- passed?
- result changed notification

Finished in 0.106647 seconds.

3 specifications (30 requirements), 0 failures

Disabled specifications

Akin to the usual Test::Unit practice, tests quickly can be disabled by replacing specify with xspecify. test/spec will count the disabled tests when you run it with SpecDox or RDox.

specrb

Since version 0.2, test/spec features a standalone test runner called specrb. specrb is like an extended version of testrb, Test::Unit’s test runner, but has additional options. It can be used for plain Test::Unit suites, too.

$ specrb -a -s -n should.output

should.output
- works for print
- works for puts
- works with readline

Finished in 0.162571 seconds.

3 specifications (6 requirements), 0 failures

See specrb --help for the usage.

Changes in version 0.3

  • should.be_close, should.be_an_instance_of, should.be_a_kind_of, and should.be_nil have been deprecated. Use the dot-variants of them. These assertions will be removed in 1.0.
  • specrb -a now includes -Ilib by default for easier out-of-the-box testing.
  • Added custom shoulds.
  • Added messaging/blaming.
  • Added disabling of specifications.
  • Small bug fixes.
  • Gem available.

Installing with RubyGems

Since version 0.3, a Gem of test/spec is available. You can install with:

gem install test-spec

(It may take some time for the index to be updated and the mirrors propagated.) I also provide a local mirror of the gems (and development snapshots) at my site:

gem install test-spec --source http://chneukirchen.org/releases/gems

Roadmap

Version 1.0 (February 2006): first stable release.

Contact

Please mail bugs, suggestions and patches to chneukirchen@gmail.com.

Darcs repository (“darcs send” is welcome for patches):
http://chneukirchen.org/repos/testspec

Thanks to

  • Eero Saynatkari for writing should.output.
  • Jean-Michel Garnier for packaging the first gem.
  • Mikko Lehtonen, Jan Wikholm, Matt Mower and Michael Fellinger for testing the gem.
  • Thomas Fuchs for script.aculo.us BDD testing which convinced me.
  • Dave Astels for BDD.
  • The RSpec team for API inspiration.
  • Nathaniel Talbott for Test::Unit.

Copying

Copyright (C) 2006, 2007 Christian Neukirchen
test/spec is licensed under the same terms as Ruby itself.

Where can I get it?

You can download test/spec 0.3 at:
http://chneukirchen.org/releases/test-spec-0.3.0.tar.gz

Alternatively, you can checkout from the development repository with:

darcs get http://chneukirchen.org/repos/testspec

(Patches using “darcs send” are most welcome.)

Happy hacking and have a nice day,
Christian Neukirchen

ea043ab5837994179d4659aa1e2fcc88  test-spec-0.3.0.tar.gz
d0e1c45c2e814cc26a7967232ca99f6c  test-spec-0.3.0.gem

NP: The Rolling Stones—Gimmie Shelter

17jan2007 · a declaration of independence

when in the course of writing ⁄ it becomes necessary for writers ⁄ to dissolve the syntactical bands ⁄ which have connected them with another ⁄ and to assume ⁄ among the powers of the written word ⁄ the laws of nature ⁄ and of nature’s rule entitle them ⁄ a decent respect to the opinions of mankind ⁄ requires that they should declare ⁄ the causes which impel them to the separation

we hold these truths to be self-evident ⁄ that all words are created equal ⁄ that they are used by their writer on purpose

whenever any form of punctuation becomes destructive to these ends ⁄ and create injustice among the words ⁄ it is the right of the writers to alter ⁄ or abolish it ⁄ and to institute new punctuation ⁄ or no punctuation at all ⁄ laying its foundation on such principles ⁄ and organizing it in such form ⁄ as to them shall seem most likely to effect their purpose

prudence will dictate that punctuation long established ⁄ should not be changed for light and transient causes ⁄ and accordingly all experience has shown ⁄ that writers are more disposed to suffer ⁄ where evils are sufferable ⁄ than to right themselves by abolishing the forms of punctuation ⁄ to which they are accustomed

but when a long train of punctuation rules ⁄ evinces a design to reduce words under absolute despotism ⁄ it is their right ⁄ it is their duty ⁄ to throw off such punctuation ⁄ and provide new punctuation for their future writing

the history of punctuation is a history of repeated injuries ⁄ and usurpations ⁄ all having in direct object the establishment ⁄ of an absolute punctuation ⁄ over our words

it has refused ⁄ to give all words the same importance ⁄ it has dictated ⁄ illogical rules of capitalization ⁄ it has forbidden ⁄ to let the writer express himself however he wants it

in every stage of oppression ⁄ we have petitioned for the most humble terms ⁄ our repeated petitions ⁄ only have been answered by repeated injury

a rule of punctuation ⁄ whose character is thus marked by every act which may define a tyrant ⁄ is unfit to be used by writers

we ⁄ therefore ⁄ writers all over the world ⁄ do ⁄ in the name ⁄ and by the authority ⁄ of our writing ⁄ solemnly publish and declare ⁄ that this new way of writing is ⁄ absolved from all allegiance to punctuation ⁄ and ⁄ all connection between them ⁄ and related parts of language ⁄ is ⁄ and ought to be ⁄ totally dissolved ⁄ and that as free writers ⁄ they have full power to levy war ⁄ conclude peace ⁄ contract alliances ⁄ establish publishing ⁄ and to do all other acts and things ⁄ which free writers may of right do

and for the support of this declaration ⁄ with a firm reliance on the protection by the readership ⁄ we mutually pledge to each other ⁄ our lives ⁄ our writings ⁄ and our sacred honor

christian neukirchen

NP: The Who—Behind Blue Eyes

10jan2007 · How Rails made me a better programmer

(Consider this an entry for the contest.)

The question how Rails made me a better programmer can be answered in a short, but incomplete and actually wrong way: It didn’t.

That is only half the truth. When Rails was released in 2004, I already had almost three years of programming experience in Ruby. Therefore, I don’t think I learned much from Rails in a technical way. I knew MVC, the code didn’t particularly impress me, and, in the end, I didn’t care a lot about web development either. At that time, at least.

The things I’ve learned (or everyone could learn) from Rails are social lessons. Some of them were to be expected, some were very unexpected and a few still make me question the universe everytime I think of them.

So, what did I learn from Rails?

  1. Community matters. The best idea is useless even in the literal sense if nobody uses it. I did not learn that directly from Rails, since Ruby had (and still has) a very nice, but at that time rather small community. (Which is not necessarily a bad thing.)

  2. Don’t underestimate the community. I primarily noticed this attending RailsConf Europe. Almost everybody I talked to really knew his/her stuff well, and lots were really experienced in Ruby, too. Of course, it was a rather small and exclusive selection of Rails users, and they had enough time to learn Ruby until September 2006.

  3. Don’t overestimate the community. Scaling a community is hard, and Rails soon got into a storm of newbies from Java and PHP camps. The eager and clever people of these can learn and pick up everything. The rest proably still lurks in #rubyonrails waiting for their answers. Just because something was made easy, it doesn’t mean it’s less complex in itself, there is less to learn or less to think. Rails may be easy to use, and quick to get started, but it’s not a silver bullet, and designing, programming and deploying a real life website is still demanding.

  4. Learn to sell. Before Rails, one rarely saw a screencast, but they are a great way to convince people of some piece of software quickly—there is no denying. The whole “PR” of Rails worked very well in the end. Everyone now knows about it. But also see 3.

  5. Opinions help you and the users. Writing a totally generic framework without any defaults and conventions turns out to be lots of effort for the users. The less opinionated the software is, the bigger the possible userbase becomes, at the cost of passion. Avoid this. Rather, enable useful (to you) defaults, and make going beyond them not cost flexibility, but convenience. The users with vastly different needs will find a different solution (cf. 7).

  6. Gauge evolution and revolution. In the end, Rails is just meta-programming the boring tasks of web development—there is nothing really revolutionary, at least compared to more “advanced” frameworks based on continuations and so on. However, this technically slight evolution had a huge effect, while a more revolutionary framework would have had an even harder time to get acknowledged and appreciated.

  7. Everything has its niche. Many thought that with Rails’ uprising the other Ruby web frameworks had no chance. It turned out to be wrong: today there are more Ruby web frameworks that ever (we still have a long way to go to catch up with Python, though ;-)). If you absolutely can’t stand Rails, of if it simply doesn’t satisfy your needs, just check them out. Or write your own.

  8. Mastering anything takes time. It’s rare nowadays, but it occasionally still happens that I discover a Ruby method/trick/dark corner that I haven’t heard of before, despite year long learning and using the language. The same is true for Rails, both for its users as well as its programmers. Lots of Rails programmers came to Ruby via Rails, and lots of them probably today bitch as much as me when I have to read some piece of their early code. That’s not a problem by itself, but one needs to recognize that even though doing Ruby for, say, half a year, mastery has not been reached. Furthermore, if you realize an often used piece of code is written in a newbie style, don’t hesitate to refactor.

  9. Success comes after the hype. There have been times I’ve pondered myself for not really liking Rails, but just like in real life, people quickly recognized that Rails is not paradise either. Just about everybody stumbled over some rough parts, got bitten by a nasty bug, or completely became befuzzled trying to add more magic to ActiveRecord. And a fair lot admit that Rails could be better than it is. However, people still use it. Even a big part of these critics uses it, and some make their money with it. Rails clearly survived the hype, and still looks good. This can be known only afterwards, though.

  10. Make programming fun. With Rails as with Ruby, one often sees the word “fun” in the same sentence as the word “programming”. As a hobbyist programmer, I pity people that need to program non-fun stuff, and I knew all the time that I vastly prefer fun programming. Guess how happy I was when I found Ruby.

NP: Bob Dylan—Visions Of Johanna

07jan2007 · Es jährt sich...

Dieses Bild hat ja schon eine lange Tradition auf “chris blogs”. Dieses Jahr gabs allerdings keinen Schnee, da mussten wir auf eine andere Kühltruhe ausweichen.

Inhalt des Gefrierschanks

NP: Minutemen—One Reporter’s Opinion

06jan2007 · 5 things you didn't know yet about me

Alas, manveru tagged me and I need to tell you five things you probably didn’t know yet about me. It’s like the perfect start into a year with the resolution of writing more.

Here’s my list:

  • I have a photographic memory for URLs. Want to show me “something new”? I’ll tell you immediately if I already have been on that site.

  • I’m a programming language fetishist. Well, if you read my blog, you probably guessed that already, but I can recognize almost every language given a short snippet and likely heard of the rest too.

  • I love to sleep long. Don’t even dare to wake me on weekends!

  • I have every official Bob Dylan disk on my hard drive. Must be the collector’s disease.

  • My mind goes all weird when I’m drunk. And I mean really weird. For example, I once couldn’t sleep in a bus because I did too many sudokus that day, and desperately tried to sleep in a different position than the people in my row and my column. Or, one time, I tried to analyze relationships in a discotheque using advanced algebra. It sucks if love isn’t commutative.

    Actually, that’s pretty funny, but rather scary too when you remember it, no?

The next people to tell five things we didn’t yet know about them are, umm, Aria, David, Ferstl, Baschde und Nici.

NP: The Kooks—See the World

Copyright © 2004–2016