For the last week I’ve been writing a Drupal utility in Ruby. This is a dubious decision, because most Drupal developers would prefer a tool written in Drupal’s native PHP. It’s less hassle to install, and less hassle to modify.
But I went with Ruby anyway, at least for version 0.1 — partly to keep myself in practice, and partly as an excuse to work out with RSpec, the Behavior Driven Development (BDD) framework for Ruby.
With BDD, before you write your code, you write a spec. Here’s a section of one of my specs — it describes an Environment object that can parse a Unix command line and pick out the arguments and the option flags:
describe Environment, "created from the command line" do
before(:each) do
@env = Environment.new
end
it "should set the usage message attribute" do
args = %w(foo bar baz quux)
@env.parse_command_line(args)
@env.usage_message.should_not be_empty
end
it "should recognize arguments that are not options" do
args = %w(foo bar baz quux)
@env.parse_command_line(args)
@env.should have(4).args
end
it "should throw an exception if an illegal option is provided" do
args = %w(foo -z bar)
lambda { @env.parse_command_line(args) }.should raise_error
end
it "should allow the cvs path to be set" do
test_path = '/bin/cvs'
args = ['--cvspath', test_path]
@env.parse_command_line(args)
@env.get_option(:cvs_command_path).should == test_path
end
it "should be invalid if cvs path does not exist" do
args = ['--cvspath', 'nonexistent']
@env.parse_command_line(args)
@env.should_not be_valid
@env.errors.should have_at_least(1).error
@env.errors_on(:cvs_path).should have(1).error
@env.errors_on(:cvs_path).should match(/not exist/)
end
end
The idea is that you write a sentence about what the code should do, along with an executable description that demonstrates the sentence. Then you write the code itself until the description runs without failing.
Advocates of Test-Driven Development (TDD) will recognize this as nearly the same thing. But it does have a few advantages:
BDD avoids using the word “test”, which carries uncomfortable connotations like “broken” and “buggy” and “ISO 9002” and “let’s do that last, after the documentation”. BDD uses words like “describe” and “should” to guide you into a proper, positive frame of mind.
BDD in Ruby uses nifty readable syntax. The syntax is astoundingly addictive. Why read this:
assert(wallet.dollars >= 2e6)
when you can read this:
wallet.should have_at_least(2e6).dollars
or this:
bank = mock('a bank with 2 million dollars')
bank.should_receive(:withdraw).at_least(:twice).with(1e6).and_return(:ok)
Oh, sweet RSpec mock syntax. How I wish you had an equivalent in other important languages, like PHP!
Well, the good news is that PHP has testing advocates of its own. Mock objects are apparently well covered by Simpletest, which just happens to be Drupal’s preferred PHP testing library. And the syntax looks familiar — it’s quite nice, despite some additional clutter:
$observer = $this->getStub('Observer', array('update'));
$observer->shouldReceive('update')->once()->with('something');
Meanwhile, at least one person, Pádraic Brady, is working on a BDD framework for PHP: the PHPSpec project. Unfortunately, the results are… less nice:
class DescribeNewBowlingGame extends PHPSpec_Context {
private $_bowling = null;
public function before() {
$this->_bowling = new Bowling;
}
public function itShouldScore0ForGutterGame() {
for ($i=1; $i<=20; $i++) {
$this->_bowling->hit(0);
}
$this->spec($this->_bowling->score)->should->equal(0);
}
}
Compare this to the RSpec code which inspired it:
describe Bowling do
before(:each) do
@bowling = Bowling.new
end
it "should score 0 for gutter game" do
20.times { @bowling.hit(0) }
@bowling.score.should == 0
end
end
It’s enough to make you cry.
The thing is, I’m completely convinced that Pádraic is doing the best he can. I am no expert on PHP syntax, having learned it by osmosis from Drupal code, and maybe after I finish Programming PHP I’ll know better, but PHPSpec seems to be fundamentally stymied by the ugly syntax of PHP. Specifically:
What’s :this?
Why, it’s PHP’s inability to understand object scoping! You would think that declaring _bowling to be private to a class would be enough of a clue, but it looks like you’re still obligated to refer to it as $this->_bowling.
Little things matter
Ruby uses object.method syntax. PHP uses $object->method. They look so comparable! That is, until you run into a chain like:
$this->spec(foo)->should->equal
which is less readable than:
this.spec(foo).should.equal
It’s all about the typography: the whitespace above the tiny dot separates the words better and makes their shape easier to recognize.
It’s good to be an Object
In Ruby, everything is an object, every object is a child of Object, and Objects can be monkey-patched. So you can magically attach new methods like should and should_not to the Object class and then write things like:
@bowling.score.should be_big
Here we’re calling the should method on @bowling.score, which is probably an Integer, although it might be a BowlingScore object, or a Real, or even Imaginary if we’re bowling on the planet Vulcan. Ruby does not care. Ruby can roll with those punches. Ruby rocks.
Alas, PHP prosaically insists that you call the should method on specific objects that can actually understand it. So we have to wrap the subject of should in a $this->spec(), like this:
$this->spec($this->_bowling->score)->should->equal(0);
This line makes my brain hurt because it’s got two instances of $this, both of which are 100% free of significant meaning. The thing which they refer to — the enclosing PHPSpec_Context object — is an irrelevant piece of scaffolding that I do not want to have to think about.
The PHP version of the Bowling spec reads like this:
This paragraph is a spec, and it-describes-Bowling. Consider the game of bowling that we will discuss in this paragraph. The score-should-be-zero-for-a-gutter-game. That is, if a ‘hit’ that scores zero pins happens twenty times, this sentence of this paragraph will be true: this paragraph’s game’s score should equal zero.
Here’s the RSpec version:
Let’s talk about Bowling. Consider a game of bowling. The score should be zero for a gutter game. That is, if a ‘hit’ that scores zero pins happens twenty times, the game’s score should equal zero.
(Note: Fun as it would be to write down the prose equivalent of a for loop — it would look like a number-theory textbook — I decided not to blame PHP for that. I’m pretty sure the language does have iterators…)
PHP’s syntactic cyanide is so bitter that I wonder: is PHPSpec worth it? If the language itself insists on mangling my syntax, why should I bother trying to apply the subtle shading that is BDD? It just gets lost in the noise. Here’s a comparison from the PHPSpec docs themselves: the TDD version (PHPUnit):
$logger = new Logger;
$this->assertTrue($logger->hasFile());
and the BDD version (PHPSpec):
$logger = new Logger;
$this->spec($logger)->should->haveFile();
Frankly, I think the first version is clearer: it’s shorter, the call to hasFile() is in its natural location, and since neither version is readable, why not pick the one that’s closest to idiomatic PHP? Others seem to agree with me; just look at this comment thread.
Pádraic has his work cut out for him, battling heroically against the fundamental structures of the PHP universe. I really feel for the guy, and would sincerely like to help. My personal inclination is to build a macro processor that allows you to write something sensible and have it JIT-compiled into PHP. But maybe I can get used to PHPSpec if I make some subtle vocabulary changes:
$this->thing($this->_bowling->score)->thing->should->equal(0)
This thing, this PHP syntax thing… we will learn to cope with it.
The freakish thing writing a BDD framework for PHP is definitely the syntax. That said I'd venture it does still have value - maybe not as much as RSpec (which I use regularly for Ruby) but enough that it can spark some improvement in other areas of PHP. I think a lot of this is simple to explain - PHP doesn't have a huge population of testing/TDD/BDD tools to start with. Any hamfisted effort is an improvement :).
As you noted SimpleTest has excellent Mock Object support, and has done for years. With PHPSpec now requiring the introduction of a PHPMock library for it's own use (since the SimpleTest one is internal) it's also been adopted by PHPUnit 4. Then there's PHPMutagen - another first for PHP.
Personally I think PHPSpec will drive progression outside it's BDD origins - at least until I figure out how to minimise PHP's inexhaustible efforts to defeat a nice looking API...sigh.
I agree with what you're saying, it makes a lot of sense. I'm just too comfortable with PHP to be taking up something different.
Maybe one day I'll be brave enough and re-visit your post for inspiration!
Mmoinn contains a great wealth of good, it gives you cheapest wow gold let you in the highest mountains in the mountains of Britain's Dun Morogh find more wealth. Dun Morogh biting wind will always accompany you. Steep cliff and the snow-covered lake, which is the Yeti, Troll and the Beast entrenched, but in this densely barren of snow and ice of
the country, some additional surprises. You can find mmoinn in
warcraft gold and wow power leveling . mmoinn is a huge support to help you save a good place, together buy wow gold you to experience the mmoinn The pleasant surprise.
You have to increase the role of the game's forces? Harlan would like to buy PvP rewards it? You can get mmoinn.com to cheapest wow gold , it is a long-standing search for your cheapest warhammer gold . When you have the largest wow gold , you can buy Harlan Harlan fight Medal and the Order of study. mmoinn.com is wow gold cheap a good place, you can world of warcraft
sale in the wow power leveling . As soon as possible to experience.
In World of Warcraft to enhance the skills and attributes?
In fact, each of the attributes of the upgrade is based on the amount of your characters race and occupation. Skill level is through you the skills in order to enhance the training. Therefore, to enhance the strength of character required huge wow gold . Mmoinn and is the best choice for you, here to provide you with the cheapest wow gold , so you can quickly find world of warcraft sale in the wow power leveling , would like to own With more wow money as soon as possible to buy mmoinn.
You need treatment? Looking for a right-assisted human shields? To seek a damage output to it?
There is a gap in need of a person as a whole to support this team? Shaman can.Shamanism is
World of Warcraftthe only real "mixed" occupation, is the clan and tribal spiritual leader. They can make use of magic and totems in the fighting or to enhance the treatment of their own teammates, the energy released from the elements can effectively crack down on the enemy. To let their talent has a more powerful shaman's magic and the medium-armor, you can mmoinn.com in buy wow gold, mmoinn.com is a professional trading platform, it can give you
cheap wow gold 。In 5 minutes you can find
Want to save huge expenditure is so easy.
For the first time to play World of Warcraft it? You must understand that this mmoinn professional wow gold platform.
Here you can find cheapest wow gold , which is cheap warhammer gold . In the game you can be friends and to experience the ultimate challenge and adventure, a taste of the fun new game! As soon as possible to buy wow gold , experience the world of warcraft sale the wow power leveling .
I'd love a book which surveyed the history of language features in Ruby inspired or copied from languages as LISP, Smaltalk, Perl, etc. Like going back to the roots and discuss why they was chosen and why it's implemented in a particular way in Ruby. Are we missing certain things these languages have to offer in Ruby? How does these choices relate to code beauty and programmer happiness?
A player must also learn riding skills, not only in the specific needs of horse trainer's own camp has a good reputation, you want to buy the role of the horse it? mmoinn can help you save big money. Mmoinn to provide you with a large number of wow gold , let you easily find World of warcraft Gold in the wow power leveling . Mmoinn You do not have to spend a lot of money, do not want to be able to save money ahead of the horse.
Sennaruisi, a collection of wizard magic forest, the tree composition of the troops and lead them to the Burning Legion launched a bold attack on the ground. Mmoinn to you as soon as possible to enhance the role of the strength of it! Here are the cheapest wow gold , you can get five minutes more warcraft gold , you
can quickly find wow power leveling , set in the Arab-night wizard Zi Shala and the Temple of eternal spring, it is necessary to combat the rising.
wow gold
wow gold
eve isk
I'd love to see a book on Capistrano 2! Especially how it can fit into existing infrastructure (php/mysql/subversion) while allowing new projects to be rails/camping/nitro/sinatra based.
Have a list of things you need from the infrastructure/server admin team as a minimum, and list things that would be nice to have.
Also stats on avg requests per second etc. for rails would be great to show a boss! Maybe even with some examples of how businesses have used rails and the benefits of it over existing frameworks.A book that talks about the Ruby internals. How the language is implemented and what defines Ruby as a language. With all the work being done implementing ruby on top of various VM's (JVM, Rubinius, YARV, .NET CLR), a book that explains how one goes about doing something like would be very very helpful.
[size=4][url=http://www.vipwargold.com/][size=4][color=#0000ff]war gold[/color][/size][/url][size=4] [/size][url=http://www.vipwargold.com/][size=4][color=#0000ff]buy war gold[/color][/size][/url][size=4] [/size][url=http://www.vipwargold.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url]
[url=http://www.cheaperzone.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url][size=4] [/size][url=http://www.cheaperzone.com/Buy-WOW-Gold/WOW-Gold.Html][size=4][color=#0000ff]buy warhammer gold[/color][/size][/url][size=4] [/size][url=http://www.cheaperzone.com/][size=4][color=#0000ff]war gold[/color][/size][/url][size=4] [/size]
[size=4][url=http://www.vipwarhammergold.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url] [url=http://www.vipwarhammergold.com/][color=#0000ff]buy warhammer gold[/color][/url] [url=http://www.vipwarhammergold.com/][color=#0000ff]war gold[/color][/url][/size]
[size=4][url=http://www.buyfastgold.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url] [url=http://www.buyfastgold.com/buy-warhammer-gold/][color=#0000ff]buy warhammer gold[/color][/url] [url=http://www.buyfastgold.com/][size=4][color=#0000ff]war gold[/color][/size][/url][/size]
[size=4][url=http://warhammer-gold.rgtrcredit.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url] [url=http://warhammer-gold.rgtrcredit.com/Buy-warhammer-gold.html][color=#0000ff]buy warhammer gold[/color][/url] [url=http://warhammer-gold.rgtrcredit.com/][color=#0000ff]war gold[/color][/url][/size]
[size=4][url=http://warhammer.hellgate-pd.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url] [url=http://warhammer.hellgate-pd.com/buy-warhammer-gold.html][color=#0000ff]buy warhammer gold[/color][/url] [url=http://warhammer.hellgate-pd.com/][size=4][color=#0000ff]war gold[/color][/size][/url][/size]
[size=4][url=http://www.warhammer100.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url] [url=http://www.warhammer100.com/][color=#0000ff]buy warhammer gold[/color][/url] [url=http://www.warhammer100.com/][color=#0000ff]war gold[/color][/url][/size]
[size=4][url=http://www.vipaocgold.com/][size=4][color=#0000ff]aoc gold[/color][/size][/url] [url=http://www.vipaocgold.com/buy-aoc-gold/][color=#0000ff]buy aoc gold[/color][/url] [url=http://www.vipaocgold.com/][color=#0000ff]age of conan gold[/color][/url][/size]
[size=4][size=4][size=4][url=http://www.aocsale.com/][size=4][size=4][color=#0000ff]age of conan gold[/color][/size][/size][/url][/size] [url=http://www.aocsale.com/buy-aoc-gold/][color=#0000ff]buy age of conan gold[/color][/url] [url=http://www.aocsale.com/][color=#0000ff]aoc gold[/color][/url][/size][/size]
[size=4][url=http://www.gold-warhammer.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url] [url=http://www.warhammer100.com/][color=#0000ff]warhammer online gold[/color][/url][/size]
[size=4][url=http://www.bestwarhammer.com/][size=4][color=#0000ff]warhammer online gold[/color][/size][/url] [url=http://www.cheaperzone.com/][color=#0000ff]warhammer online gold[/color][/url][/size][size=4][/size]
[size=4][url=http://www.bestwarhammer.com/][size=4][color=#0000ff]warhammer gold[/color][/size][/url] [url=http://www.bestwarhammer.com/][color=#0000ff]buy warhammer gold[/color][/url] [url=http://www.bestwarhammer.com/][color=#0000ff]war gold[/color][/url][/size]
[url=http://www.bestwarhammer.com/][color=#0000ff][/color][/url][/size]
online roulette
link: wow gold | wow power leveling | wow gold
Would like to get five minutes on the wow gold ? In order to search for cheapest wow gold worry about? http://www.mmoinn.com be able to solve all your problems, we give you wow power leveling and so forth, You play the role with ease. MMOinn is great and the order tracking process is super.
Post new comment