For example, in a Rails gemfile:
group :development, :test do
gem 'rspec-rails', '~> 2.0'
end
what is going on with the do
... end
statement? And with rspec:
describe "Foo" do
context "bar" do
expect...
end
end
are the do
... end
-s creating a block whose information in between is being used elsewhere? How is this working without setting a block parameter?
This is called Domain-Specific Language
A Domain-Specific Language, or DSL, is “a programming language of limited expressiveness focused on a particular domain”. It makes tasks in its domain easier by removing extraneous code for a particular task and allowing you to focus on the specific task at hand. It also helps other people read the code, because the purpose of the code is so clear.
Basically this
group :development, :test do
gem 'rspec-rails', '~> 2.0'
end
is just a call of the method group
with arguments :development, :test
and with a block gem 'rspec-rails', '~> 2.0'
. Which is defined in this way in Bundler DSL:
def group(*args, &blk)
...
end
Same for your second example.
DSL defines methods to group examples, most notably describe, and exposes them as class methods of RSpec.
.describe
is being implemented in this way:
def describe(doc_string, *metadata_keys, metadata = {}, &example_implementation)
...
end
You can read more about writing Domain-Specific Language in Ruby in this thoughtbot.com article
Receiving a block parameter is optional. If you are not using block variables, you don't have to write |...|
even if the block is called with block variables.
def foo &block
block.call(:foo)
end
foo{|v| puts "I received `:foo', but am not using it."}
foo{puts "I am called with `:foo', but am not receiving it."}
And also if the method is defined not to pass any block variable, then you don't need |...|
in the block.
def bar &block
block.call
end
bar{puts "I am not called with a block variable in the first place."}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With