I have a method that looks like the method below, and I can't help but shake the feeling that it can be improved. It doesn't really "read" well, and it seems like checkout
could be called only once, somehow.
def ensure_correctness
if exist?
unless correct_version?
delete!
checkout
end
else
checkout
end
end
def checkout
run_command(['git', 'clone', '--depth', '1', url, path])
end
def exist?
Dir.exist?(path)
end
def delete!
FileUtils.rm_rf(path)
end
def correct_version?
commit_sha_short == desired_commit_sha_short
end
The best I could come up with is moving the code from failing correct_version?
to a new method (which probably isn't a terrible idea, but I wonder if I can do better).
I feel like I'm missing something really obvious here...
2 Answers 2
The two calls to checkout
look well to me. They are simple method calls to self with no arguments, and I can easily see that both calls are the same. You avoid making two identical calls to run_command(['git', 'clone', ...])
.
The "something really obvious" might be a return
:
def ensure_correctness
if exist?
return if correct_version?
delete!
end
checkout
end
-
\$\begingroup\$ Yes! Thank you for addressing the more abstract problem! I believe you are correct about the "something really obvious", but I wonder if there is a way to achieve the same thing in a different arrangement without the return... If I can't think of any, I'm going to mark this as accepted, as it most closely satisfies my original curiosity. \$\endgroup\$Brad Werth– Brad Werth2017年12月02日 00:51:15 +00:00Commented Dec 2, 2017 at 0:51
-
\$\begingroup\$ Just out of curiosity, which of the three solutions do you consider to be more idiomatic/readable? \$\endgroup\$Brad Werth– Brad Werth2017年12月02日 00:53:14 +00:00Commented Dec 2, 2017 at 0:53
-
1\$\begingroup\$ Your
correct_version? || delete! && checkout
confused me because of operator precedence. I first thought of Unix shell (sh), where||
and&&
have same precedence. Then I remembered that Ruby does&&
before||
. The code might be more readable to people who don't know sh. \$\endgroup\$George Koehler– George Koehler2017年12月02日 01:12:41 +00:00Commented Dec 2, 2017 at 1:12
While I envisioned just moving the instructions in ensure_correctness
around a little, to find an efficient solution to a pattern a see repeated with some frequency, it turns out it was better to rearrange everything a little. I think the final solution is more attractive, even if it does potentially call delete!
unnecessarily (it doesn't matter).
def ensure_correctness
unless correct_version?
delete!
checkout
end
end
def checkout
run_command(['git', 'clone', '--depth', '1', url, path])
end
def exist?
Dir.exist?(path)
end
def delete!
FileUtils.rm_rf(path)
end
def correct_version?
exist? && commit_sha_short == desired_commit_sha_short
end
-
\$\begingroup\$ I think ultimately this solution works better for the application than the accepted answer, both in terms of readability and robustness. The adjustment has the side-effect of making the
correct_version
method technically more correct, which could be useful if consumed from elsewhere. I really appreciate everyone that took a look at this question - thanks! \$\endgroup\$Brad Werth– Brad Werth2017年12月02日 00:51:39 +00:00Commented Dec 2, 2017 at 0:51 -
\$\begingroup\$ Personally I would prefer parenthesis around
delete! && checkout
, but that might just be because I am not used to Ruby's operator precedence and that I prefer to avoid combining&&
and||
on the same line. \$\endgroup\$Simon Forsberg– Simon Forsberg2017年12月02日 01:22:48 +00:00Commented Dec 2, 2017 at 1:22 -
\$\begingroup\$ That "less confusing" way is wrong, should use
unless
instead ofif
. And you rely onFileUtils.rm_rf
returning something "true" but the documentation doesn't specify any return value. Is that safe? (Also, if someone changeddelete!
so it returns something "false", that would break it as well. And sincedelete!
isn't documented at all, one might feel free to make such a change, not knowing that it breaks something.) \$\endgroup\$Stefan Pochmann– Stefan Pochmann2017年12月03日 12:16:06 +00:00Commented Dec 3, 2017 at 12:16 -
\$\begingroup\$ @StefanPochmann, you're right, good catch! Updated answer, thanks. \$\endgroup\$Brad Werth– Brad Werth2017年12月03日 15:40:41 +00:00Commented Dec 3, 2017 at 15:40
operation_1
? I agree with the above comment though, the more context you can add the better, really. \$\endgroup\$