[rspec-devel] [ rspec-Feature Requests-13837 ] alias :running, :lambda

noreply at rubyforge.org noreply at rubyforge.org
Thu Sep 20 09:08:56 EDT 2007

Feature Requests item #13837, was opened at 2007-09-11 09:46
You can respond by visiting: 

Category: expectation module
Group: None
Status: Closed
Priority: 3
Submitted By: sudara williams (sudara)
Assigned to: David Chelimsky (dchelimsky)
Summary: alias :running, :lambda

Initial Comment:
For everyday Rspec "reads like english" purposes, aliasing lambda as "running" would make for some fun spec writing:

running { something_risky }.should raise_error 
running { Fancy.operation }.should_not change(@simple, :factor)

or even

running { to_the_bathroom }.should_not change(person, :weight)

describe "A clear spec language" do
	it "should replace generic lowlevel language with intuitive goodies" do
  	running { 5.to_s }.call.should == lambda { 5.to_s }.call		


Comment By: Wincent Colaiuta (wincent)
Date: 2007-09-20 13:08

I actually quite like this proposal, despite the arguments against it. I think that RSpec is all about readable specs -- that is *the* reason I migrated from Test::Unit -- and that if a programmer can learn what "describe", "it", "should" and "should_not" are for, then he/she will have no trouble remembering that "running" is an alias for "lambda".

But I also suspect that if both David and Aslak don't like it then there's not much point in continuing the discussion.


Comment By: sudara williams (sudara)
Date: 2007-09-13 11:26

Double Fuggles! No patronizing is in my heart. "Read
something deeper, please" is a simple response to the "It is
ruby, alias it yourself," which avoids the real discussion
and 95% of what I desire to communicate. 

The string solution is interesting. 

How about this:

The core reason for the usage of lambda (forcing a different
pattern for some Rspec matchers, a confusing metaprogamming
trick for noobees, and a break from readability) seems to be
the need to run code before and after the code specified in
the "it" block. In the case of raise_error, we need to catch
exceptions. In the case of should change, we need to grab a
value before and after, and then compare those two.

How about refactoring the pattern from "User uses lambda and
a special matcher. Matcher executes code, calls lambda,
executes code, evaluates" 


"If the matcher requires before and after code, we callback
for it before and after running the matcher" 

The benefits would be good - improved consistency and dsl,
and it would also open up matchers to be more flexible. 

That being said, I've stared at the Spec::DSL stuff for the
last 30 min and don't find myself smart enough to really see
how that would work. Maybe it can't. What do you think?

Anywho, I'm 150% fine with moving on and accepting the
current dsl, I just wanted to voice my suggestion- an
opportunity for improvement. I've kicked in maybe 50 hours
with Rspec so far, and though it was slow going at the
start, I really really really really really like the
attitudes and processes that you guys are promoting. I've
grown a lot as a developer because of it.

Thank you,



Comment By: David Chelimsky (dchelimsky)
Date: 2007-09-12 15:59

class String
  def call

I think that should do it, no?


Comment By: Jay Levitt (jaylev)
Date: 2007-09-12 15:47

Oo, that's pretty too.  I understand that lambda is a common Ruby-ism, but at the moment, nothing I do (or expect to do in Rails) needs it -except- for rspec, and I don't like to have to think in metaprogramming mode unless I need to.

If the eval method is easy to code, works the same as lambda does today, doesn't create any maintenance nightmares, etc., I'd +1 that..


Comment By: David Chelimsky (dchelimsky)
Date: 2007-09-12 15:37

"My hope is that you guys can read something deeper
in my request" strikes me as patronizing and not very helpful. If you're interested in helping us to learn something that we may be missing, please continue to do so respectfully, by example.

As I see it, you would like to see RSpec read even more like English. The complicating factor is that we're really trying to ride a fine line between English and Ruby. The examples are supposed to serve as documentation at both high and low levels.

At the high level, we have the strings that allow you to express things at whatever level is appropriate for the audience. If you're spec'ing a class, you can choose terminology that speaks to developers. If you're spec'ing a more high-level behaviour, something you might collaborate with customers on, you can choose domain specific terminology.

At the low level, we have code. In the end, that code needs to tell its story to the developer. In fact, it has been argued that sexy little tricks like collection.should be_empty does not serve well as documentation for the developer. I believe that this argument has merit.

Early on, we recognized that should_equal, while aesthetically pleasing, also hid the Ruby story, which is that there are several ways to define equality, each with their own semantics and significance. In this case we preferred Ruby over English, supporting methods that align directly to Ruby methods.

In terms of lambda, this is definitely a Ruby term. No argument there. The question then becomes a matter of goals. We can talk about aesthetics, but whose aesthetic sense are we serving by using 'running' vs 'lambda'?

All of this said, there is another approach that comes closer to something you suggested in a previous comment:

Basket.add_apple.should change(@fruit, :count)

We can't really support that without getting into continuations (no thank you), and even then I'm not convinced we wouldn't suffer some ugly side effects. That said, we *could* do this:

'Basket.add_apple'.should change('fruit.count')

We'd have to eval both strings, which you could argue doesn't help any, but it does read more "ideally."



Comment By: sudara williams (sudara)
Date: 2007-09-12 14:08


lambda = Ruby
Sudara.should alias(:lambda) if Sudara.doesnt_like_it

Got it. My hope is that you guys can read something deeper
in my request.


Comment By: Matt Aimonetti (matt_a)
Date: 2007-09-12 13:20

I agree with Aslak. lambda is part of the Ruby language, it's well documented and if you are a Ruby developer you surely know and understand what it does.  

Also, aliases are easy enough to add so it shouldn't be a big deal for you to add your own.


Comment By: sudara williams (sudara)
Date: 2007-09-12 12:39


The only thing lambda screens in my face is "what a terribly
unhelpful name!" I'll relax ;) A programmer's love for the
obscure is only a variation of human love for the familiar. 

My point with Rspec:

lambda (despite it being a familiar idiom to non-beginners)
has a single use in Rspec - to specify a code block that
will be run as a part of evaluating a more complex match. In
other words, Rspec needs to run some code before and after
this block in order to do it's magic. 

Long story short, my opinion Rspec asks me to hack itself
using a technique that just aint readable, making for a
heavy feeling.

>From a DSL point of view (aka, learning Rspec) there is no
real way to differentiate matchers that need it. The More
Complicated Ones. Idiomatically, lambda is being used as a
helper within Rspec internals. Using it, Rspec can go about
wrapping my lambda with some code and then executing it.
That is the idiom in place here, and that idiom is much
better expressed as "running." After all, this is the DSL
we'd really love to have, eh?

Basket.add_apple.should change(@fruit, :count

Thanks for listening, and I'll walk away from this happy to
learn and without expecting um that anything.should change


Comment By: Scott Taylor (smtlaissezfaire)
Date: 2007-09-12 01:40

I must say I agree with Aslak, because lambda screams in my face *delayed evaluation* 

The reason I suggested run was that a co-worker (who is new to rspec) suggested it.  He comes from Test::Unit and keeps on making this mistake:

my_method.should raise_error

If the code doesn't raise an error (say it returns nil) - then the error message will read something like the following:

NoMethodError: nil.call ...

(Obviously here the proc is trying to be called...) So maybe a better error message would work in this case?

(ps: What is the internal vs. external DSL conversation?)


Comment By: David Chelimsky (dchelimsky)
Date: 2007-09-11 22:19

Based on recent conversations re: internal vs external DSL's, I have to go w/ Aslak on this one. It's important that your customers understand the Strings you pass to describe and it. It's important that your fellow programmers understand the code in the block.


Comment By: Aslak Hellesøy (aslak_hellesoy)
Date: 2007-09-11 22:10


While I value readability, I value idioms more.

lambda is at ruby's core and it's a common idiom - I don't want an alias for it, but everyone is free to make their own alias.


Comment By: Jay Levitt (jaylev)
Date: 2007-09-11 21:27

"run" doesn't read as English, though... 

running {this}.should do_that


Comment By: Scott Taylor (smtlaissezfaire)
Date: 2007-09-11 21:26

How about run { do_something }.should raise_error ?


Comment By: Jay Levitt (jaylev)
Date: 2007-09-11 09:55



You can respond by visiting: 

More information about the rspec-devel mailing list