Feature Requests item #13837, was opened at 2007-09-11 05:46
You can respond by visiting:
http://rubyforge.org/tracker/?func=detail&atid=3152&aid=13837&group_id=797
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
end
end
----------------------------------------------------------------------
Comment By: Jay Levitt (jaylev)
Date: 2007-09-12 11:47
Message:
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 11:37
Message:
"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."
WDYT?
----------------------------------------------------------------------
Comment By: sudara williams (sudara)
Date: 2007-09-12 10:08
Message:
Yikes!
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 09:20
Message:
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 08:39
Message:
Awwww....
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-11 21:40
Message:
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 18:19
Message:
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 18:10
Message:
-1
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 17:27
Message:
"run" doesn't read as English, though...
running {this}.should do_that
----------------------------------------------------------------------
Comment By: Scott Taylor (smtlaissezfaire)
Date: 2007-09-11 17:26
Message:
How about run { do_something }.should raise_error ?
----------------------------------------------------------------------
Comment By: Jay Levitt (jaylev)
Date: 2007-09-11 05:55
Message:
+1!!
----------------------------------------------------------------------
You can respond by visiting:
http://rubyforge.org/tracker/?func=detail&atid=3152&aid=13837&group_id=797