In Rspec, let uses lazy instantiation so let(:foo) { create(...) } isn't initialised until something calls it. Usually this is good, because it is only used when needed and makes rspec testing times much quicker.
Occasionally however you will have a spec that needs that variable but doesn't explicitly call it. So with lazy instantiation, the spec will fail.
A solution is with a bang! let!(:foo) { create(...) } will force that the variable is initialised.
Some developers seem to be very against this and prefer:
let(:foo) { create(...) }
before do
foo
end
to force the initialisation.
Is there a reason for this? is there any difference between the two methods?
I can think of one difference: before blocks would compound, and you can overwrite let! with let and vice versa. I'll give you an example:
context do
let!(:foo) { create(:foo) }
let(:bar) { create(:bar) }
before { bar }
context do
# if in this context you wish to switch back to "lazy" versions you can
# do that for :foo, just do:
let(:foo) { create(:foo) }
# but you can't "undo" before, even if you define an empty one:
before { }
# it does not cancel the `before` blocks defined in higher contexts
end
end
Edit: I just realized this does not really answer the question why someone would prefer before to let!. Maybe: as mentioned in comments the order is different, but if you depend on such nuance in your specs - it's already too complicated.
Many situations is a matter of style, and the developer is not full aware of main functionalities of RSpec and many times people just don't make sense. Humans are not machines, and specially under time pressure, developers do things that they wouldn't do in ideal conditions :).
But the both cases presented they are not strictly the same.
For example, if you are using subject, it is evaluated in a before hook before the let! initialization and not inside it. I didn't test, but I believe these cases should show the diffs:
let!(:car) { create(:car) }
let(:driver) { create(:driver) }
subject { driver.car() }
it { expect(subject).to eq car } # Fail:
This forces car being created before and being available for subject:
let(:driver) { create(:driver) }
subject { driver.car() }
before { create(:car) }
it { expect(subject).to eq car } # Success
Related
I'm currently designing a class structure for a project I'm working on. I have a method that uses one instance state. I don't now wheter it's better to make this method static and parse this instance state as an argument or just tie the method to the instance.
If performance was no issue I would tie the method without any doubt to the instance, because it's much cleaner that way. But in my case performance will be really crucial. So, does it make any difference performance-wise to make the method static / non-static?
If it makes no difference, will that be true for the generated *.dart.js javascript aswell?
Edit:
After reading my own question it's not really coherent. I will try to formulate it again, but clearer.
This code ...
class MyClass {
void foo() {}
}
void main() {
MyClass a = new MyClass();
MyClass b = new MyClass();
print(a.foo == b.foo);
}
... outputs false. This make me think that for each new instance a new method is created. If that is true this seems to me as a waste of memory. So, does each new instance create a copy of all it's bound methods?
PS: The question is basically the same as this question, but then for Dart.
No, creating two instances doesn't duplicate the methods. Methods are like static functions where the object instance is passesd as argument with the name this.
Don't worry too much about performance before you run into actual performance issues especially at such micro-level.
Usually performance isn't a matter for the bigger part of your applications code base because most of the code is usually run very seldom.
When you run into performance issues you can investigate and find the real hot spots that are executed often enough so that optimization actually makes a difference.
Dart classes don't have different methods for different instances.
There is only one method per class.
Extracting a function creates a new function object every time you do it, and those objects may or may not be equal depending on which function you extract from which objects:
class MyClass {
void foo() {}
}
void main() {
MyClass a = new MyClass();
MyClass b = new MyClass();
print(a.foo == b.foo); // False.
print(a.foo == a.foo); // True
print(identical(a.foo, a.foo)); // False!
}
When you perform a method extraction from an object, you create a new object. The new object is a "closure" which contains the function to call and the object to call it on. Two such closures are equal (according to operator==) if they refer to the same function on the same object. That's why a.foo and b.foo are not equal - they are equivalent to () => a.foo() and () => b.foo() respectively, and since a and b are not the same object, the function objects are not considered equal.
I'm getting this violation on sonarqube Nested If Depth
if (some condition){
some code;
if (some condition) {
some code;
}
}
and also here:
for (some condition) {
if (some condition) {
some code;
}
}
how can I reduce the depth?
Answer is already accepted, but doesn't answer the actual question.
So for completeness sake I want to add my 2 cents.
For reference see This question here
The example you list looks like it is dealing with guard conditions. Things like "only run this method if ...." or "only perform this loop iteration if ...."
In these cases, if you have 3 or 4 groups of guards you might end up indenting very deeply, making the code harder to read.
Anyways the way to fix this code to be more readable is to return early.
instead of
if (some condition) {
// some code
if (some other condition) {
// some more code
}
}
You can write
if (!some condition) {
return;
}
// some code
if (!some other condition) {
return;
}
// some more code
You now only every have 1 level of nesting and it is clear that you do not run this method unless 'some condition' has been met.
The same goes for the loop, using continue:
for (some condition) {
if (some other condition) {
// some code;
}
}
becomes
for (some condition) {
if (!some other condition) {
continue;
}
// some code
}
What you would state here is that unless 'some other condition' is met, you skip this loop.
The real question is why is the max depth set to 1 ? It's overkill.
This kind of rule is meant to keep your code readable. More than 2 nested blocks can make the code unreadable, but 1-2 will always be readable.
If you decide to keep the max depth set to 1, you need to refactor your code and put every 2nd condition check inside a separate method. No offense, but unless you have a very specific and good reason to do it, it looks like a bit stupid.
I'm writing some training material for the Groovy language and I'm preparing an example which would explain Closures.
The example is a simple caching closure for "expensive" methods, withCache
def expensiveMethod( Long a ) {
withCache (a) {
sleep(rnd())
a*5
}
}
So, now my question is: which of the two following implementations would be the fastest and more idiomatic in Groovy?
def withCache = {key, Closure operation ->
if (!cacheMap.containsKey(key)) {
cacheMap.put(key, operation())
}
cacheMap.get(key)
}
or
def withCache = {key, Closure operation ->
def cached = cacheMap.get(key)
if (cached) return cached
def res = operation()
cacheMap.put(key, res)
res
}
I prefer the first example, as it doesn't use any variable but I wonder if accessing the get method of the Map is slower than returning the variable containing the computed result.
Obviously the answer is "it depends on the size of the Map" but, out of curiosity, I would like to have the opinion of the community.
Thanks!
Firstly I agree with OverZealous, that worrying about two get operations is a premature optimization. The second exmaple is also not equal to the first. The first allows null for example, while the second on uses Groovy-Truth in the if, which means that null evals to false, as does for example an empty list/array/map. So if you want to show calling Closure I would go with the first one. If you want something more idiomatic I would do this instead for your case:
def expensiveMethod( Long a ) {
sleep(rnd())
a*5
}
def cache = [:].withDefault this.&expensiveMethod
In my answer to my own question here I posted some code and #Dave Newton was kind enough to provide me with a gist and show me the error in my not-so-Groovy ways. <-- Groovy pun
I took his advice and revamped my code to be Groovier. Since then the link I am making (which Dave represents with the replaceWith variable) has changed. Now the closure representation of what I want to do would look like this:
int i = 1
errorList = errorLinksFile.readLines().grep { it.contains "href" }.collect { line ->
def replaceWith = "<a href=\"${rooturl}${build.url}parsed_console/log_content.html#ERROR${i++}\">"
line.replaceAll(pattern, replaceWith).minus("</font>")
}
And the for loop representation of what I want to do would look like this:
def errorList = []
def i = 1
for(line in errorLinksFile.getText().split("\n")){
if(!line.contains("href")){
continue
}
errorList.add(line.replaceAll(pattern, "<a href=\"${rooturl}${build.url}parsed_console/log_content.html#ERROR${i++}\">").minus("</font>"))
}
The closure version is definitely more concise, but I'm worried if I always go the "Groovier" route the code might be harder for other programmers to understand than a simple for loop. So when is Groovier better and when should I opt for code that is likely to be understood by all programmers?
I believe that a development team should strive to be the best and coding to the least knowledgeable/experienced developer does not support this. It is important that more than one person on the team knows how to read the code that is developed though. So if you're the only one that can read it, teach someone else. If you're worried about someone new to the team being able to read it I feel that they would be equally hard to read since there would be lack of domain knowledge. What I would do though is break it up a little bit:
def originalMethod() {
//Do whatever happens before the given code
errorList = getModifiedErrorsFromFile(errorLinksFile)
}
def getModifiedErrorsFromFile(errorLinksFile) {
int i = 1
getHrefsFromFile(errorLinksFile).collect { line ->
def replaceWith = getReplacementTextForLine(i)
i++
line.replaceAll(pattern, replaceWith).minus("</font>")
}
}
def getHrefsFromFile(errorLinksFile) {
errorLinksFile.readLines().grep { it.contains "href" }
}
def getReplacementTextForLine(i) {
"<a href=\"${rooturl}${build.url}parsed_console/log_content.html#ERROR${i}\">"
}
This way if the next person doesn't immediately understand what is going on they should be able to infer what is going on based on the method names. If that doesn't work adding tests would help the next person understand what is going on.
My 2 cents. Good topic though!!!
Idiomatic groovy is good, people will learn the common idioms quickly. "Clever" groovy, in my opinion, is more likely to be just confusing.
Consider:
if (something) {
// Code...
}
With CodeRush installed it recommended doing:
if (!something) {
return;
}
// Code...
Could someone explain how this is better? Surely there is no benefit what so ever.
Isolated, as you've presented it - no benefit. But mark4o is right on: it's less nesting, which becomes very clear if you look at even, say a 4-level nesting:
public void foo() {
if (a)
if (b)
if (c)
if (d)
doSomething();
}
versus
public void foo() {
if (!a)
return;
if (!b)
return;
if (!c)
return;
if (!d)
return;
doSomething();
}
early returns like this improve readability.
In some cases, it's cleaner to validate all of your inputs at the beginning of a method and just bail out if anything is not correct. You can have a series of single-level if checks that check successively more and more specific things until you're confident that your inputs are good. The rest of the method will then be much easier to write, and will tend to have fewer nested conditionals.
One less level of nesting.
This is a conventional refactoring meant for maintainability. See:
http://www.refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html
With one condition, it's not a big improvement. But it follows the "fail fast" principle, and you really start to notice the benefit when you have lots of conditions. If you grew up on "structured programming", which typically recommends functions have single exit points, it may seem unnatural, but if you've ever tried to debug code that has three levels or more of nested conditionals, you'll start to appreciate it.
It can be used to make the code more readable (by way of less nesting). See here for a good example, and here for a good discussion of the merits.
That sort of pattern is commonly used to replace:
void SomeMethod()
{
if (condition_1)
{
if (condition_2)
{
if (condition_3)
{
// code
}
}
}
}
With:
void SomeMethod()
{
if (!condition_1) { return; }
if (!condition_2) { return; }
if (!condition_3) { return; }
// code
}
Which is much easier on the eyes.
I don't think CodeRush is recommending it --- rather just offering it as an option.
IMO, it depends on if something or !something is the exceptional case. If there is a significant amount of code if something happens, then using the !something conditional makes more sense for legibility and potential nesting reduction.
Well, look at it this way (I'll use php as an example):
You fill a form and go to this page: validate.php
example 1:
<?php
if (valid_data($_POST['username'])) {
if (valid_data($_POST['password'])) {
login();
} else {
die();
}
} else {
die();
}
?>
vs
<?php
if (!valid_data($_POST['username'])) {
die();
}
if (!valid_data($_POST['password'])) {
die();
}
login();
?>
Which one is better and easier to maintain? Remember this is just validating two things. Imagine this for a register page or something else.
I remember very clearly losing marks on a piece of college work because I had gone with the
if (!something) {
return;
}
// Code...
format. My lecturer pontificated that it was bad practice to have more than one exit point in a function. I thought that was nuts and 20+ years of computer programming later, I still do.
To be fair, he lived in an era where the lingua franca was C and functions were often pages long and full of nested conditionals making it difficult to track what was going on.
Then and now, however, simplicity is king: Keeping functions small and commenting them well is the best way to make things readable and maintainable.