4. # Clarifying comments are not
# documentation
# Converts the object into textual markup given a specific `format`
# (defaults to `:html`)
#
# == Parameters:
# format::
# A Symbol declaring the format to convert the object to. This
# can be `:text` or `:html`.
#
# == Returns:
# A string representing the object in a specified
# format.
#
def to_format(format=:html)
# format the object
end
5. # Clarifying comments are not
# documentation
# Converts the object into textual markup given a specific format.
#
# @param [Symbol] format the format type, `:text` or `:html`
# @return [String] the object converted into the expected format.
def to_format(format = :html)
# format the object
end
6. # Clarifying comments are not
# legal statements
# Copyright (C) 2012 by Nate Davis Olds. All rights reserved.
# Released under the terms of the GNU General Public License version 2 or later.
7. # Clarifying comments are not
# reminder notes
# FIXME high priority for next
deploy
def process
raise “n”
end
# OPTIMIZE refactor this code to
get more done
def goodnight
sleep 6.hours
end
# TODO any other way to do this?
def process(str=’inter’)
“use “ + str + ”polation”
end
8. # Clarifying comments are not
# reminder notes
# FIXME high priority for next $ rake notes
deploy (in /home/foobar/commandsapp)
def process app/controllers/admin/users_controller.rb:
raise “n” * [ 20] [TODO] any other way to do this?
end * [132] [FIXME] high priority for next
deploy
# OPTIMIZE refactor this code to
get more done app/model/person.rb:
def goodnight * [ 13] [OPTIMIZE] refactor this code to get
sleep 6.hours more done
end
# TODO any other way to do this?
def process(str=’inter’)
“use “ + str + ”polation”
end
9. # The attention of the comment
# is outside the scope
# of the accompanying code
# used by rake for task management
# TODO any other way to do this?
def process(str=’inter’)
“use “ + str + ”polation”
end
# used by yard
# Converts the object into textual markup given a specific format.
#
# @param [Symbol] format the format type, `:text` or `:html`
# @return [String] the object converted into the expected format.
def to_format(format = :html)
# format the object
end
# used by courts
# Copyright (C) 2012 by Nate Davis Olds. All rights reserved.
# Released under the terms of the GNU General Public License version 2 or later.
10. # A clarifying comment’s attention is
# directed internally
# inserts a string between two other strings
def process(str=’inter’)
“use “ + str + ”polation”
end
11. # Clarifying comments are
# explanations
# of the code that follows.
# inserts a string between two other strings
def process(str=’inter’)
“use “ + str + ”polation”
end
12. # Clarifying comments are
# redundant
# of the code that follows.
# inserts string
def insert_string(str=’inter’)
“use “ + str + ”polation”
end
13. # Clarifying comments are
# apologizes
# of the code that follows.
# This code sucks! I know it. You know it.
# I am sorry that you have to read it.
def is_this_example_good
100.times { ”No! it sucks!” }
end
# I’m drunk.
def string_theory_patterns
...
end
14. # Clarifying comments are
# rants
# of the code that follows.
# At this point, I'd like to take a moment to speak to you about the Adobe PSD
# format. PSD is not a good format. PSD is not even a bad format. Calling it
# such would be an insult to other bad formats, such as PCX or JPEG. No, PSD
# is an abysmal format. Having worked on this code for several weeks now, my
# hate for PSD has grown to a raging fire that burns with the fierce passion
# of a million suns.
#
.....
# Earlier, I tried to get a hold of the latest specs for the PSD file format.
# To do this, I had to apply to them for permission to apply to them to have
# them consider sending me this sacred tome. This would have involved faxing
# them a copy of some document or other, probably signed in blood. I can only
# imagine that they make this process so difficult because they are intensely
# ashamed of having created this abomination. I was naturally not gullible
# enough to go through with this procedure, but if I had done so, I would have
# printed out every single page of the spec, and set them all on fire. Were it
# within my power, I would gather every single copy of those specs, and launch
# them on a spaceship directly into the sun.
#
# PSD is not my favourite file format.
15. # Clarifying comments are
# open letters
# of the code that follows.
# Dear maintainer:
#
# Once you are done trying to 'optimize' this routine,
# and have realized what a terrible mistake that was,
# please increment the following counter as a warning
# to the next guy:
#
# total_hours_wasted_here = 42
#
16. # Clarifying comments are
# warnings
# of the code that follows.
# After you run this code, take the day off.
# It won’t finish until tomorrow.
def im_compiling(stop_at=14.hours.from_now)
if stop_at < Time.zone.now
puts "done."
else
print "."
sleep 10
im_compiling stop_at
end
end
17. # Clarifying comments are
# dialogs
# of the coder that follows.
# This is brilliant!
# Thanks. It’s nap time.
def im_compiling(stop_at=14.hours.from_now)
if stop_at < Time.zone.now
puts "done."
else
print "."
sleep 10
im_compiling stop_at
end
end
18. # Clarifying comments are
# inside jokes
# of the code that follows.
stop() # hammertime
19. # Clarifying comments are
# misleading descriptions
# of the code that follows.
# Returns the standard utility allowance
# based on how many utilities someone pays.
def standard_utility_allowance
324
end
20. # Clarifying comments are
# stashed code
def standard_utility_allowance # of the code that follows.
324
# Uncomment this by March 3, 2012 when estimations switch back
#
# case @answers[:utility_allowance]
#
# when 'Pays for Heating or # Cooling or receives MEAP or EUSP'
# 394.0
#
# when "Doesn't pay for heating or cooling but pays two other utilities"
# 239.0
#
# when "Doesn't pay for heating or cooling but pays one utility bill (NOT telephone)"
# @answers[:actual_utility_cost]
#
# when "Pays telephone only"
# 40.0
#
# else
# 0.0
# end
end
21. # Clarifying comments are
# deserted code
# of the code that follows.
def standard_utility_allowance
case @answers[:utility_allowance]
when 'Pays for Heating or # Cooling or receives MEAP or EUSP'
394.0
# when "Doesn't pay for heating or cooling but pays two other utilities"
# 239.0
when "Doesn't pay for heating or cooling but pays one utility bill (NOT telephone)"
@answers[:actual_utility_cost]
when "Pays telephone only"
40.0
else
0.0
end
end
23. # Why should clarifying comments be removed?
# Clarifying comments are codejunk
24. # Why should clarifying comments be removed?
# Clarifying comments are codejunk
term from Katrina Owen # talk entitled Therapeutic Refactoring on
confreaks from Cascadia Ruby Conference
25. # Why should clarifying comments be removed?
# Clarifying comments are codejunk
term from Katrina Owen # talk entitled Therapeutic Refactoring on
confreaks from Cascadia Ruby Conference
codejunk is a play from Edward Tufté term chartjunk 1
1 Tufte, Edward R. (1983). The Visual Display of Quantitative Information. Cheshire, CT: Graphics Press.
26. Chartjunk refers to all visual elements in charts and
graphs that are not necessary to comprehend the
information represented on the graph, or that
distract the viewer from this information.
27. Codejunk refers to all visual elements in code that
are not necessary to comprehend the information
represented in the code, or that distract the viewer
from this information.
28. Understanding Code
70%
New Code
5%
Modifying Existing Code
25%
# http://blogs.msdn.com/b/peterhal/archive/2006/01/04/509302.aspx Peter Hallam
32. # Isn’t that why we write clarifying comments?
No. We write clarifying
comments because our code
isn’t clear enough.
33. The use of a clarifying
comment admits the failure
to write readable, clean code
34. The use of a clarifying
comment admits the failure
to write readable, clean code
# Stop clarifying code with comments;
# Write code clearly instead.
36. # explanations
# inserts a string between two other strings
def process(str=’inter’)
“use “ + str + ”polation”
end
37. # explanations
# inserts a string between two other strings
def process(str=’inter’)
“use “ + str + ”polation”
end
# rename function
def insert_string(str=’inter’)
“use “ + str + ”polation”
end
42. # apologizing
# This code sucks! I know it. You know it.
# I am sorry that you have to read it.
def is_this_example_good
100.times { ”No! it sucks!” }
end
43. # apologizing
# This code sucks! I know it. You know it.
# I am sorry that you have to read it.
def is_this_example_good
100.times { ”No! it sucks!” }
end
# make it better
def is_this_example_good
1000.times { ”Awesome” }
end
45. # rants
# At this point, I'd like to take a moment to speak to you about the Adobe PSD
# format. PSD is not a good format. PSD is not even a bad format. Calling it
# such would be an insult to other bad formats, such as PCX or JPEG. No, PSD
46. # rants
# At this point, I'd like to take a moment to speak to you about the Adobe PSD
# format. PSD is not a good format. PSD is not even a bad format. Calling it
# such would be an insult to other bad formats, such as PCX or JPEG. No, PSD
# blog about it. tweet it. Or give a presentation about it. Just Remove it from code.
Why I hate Adobe PSD format!
by I. Rant
At this point, I'd like to take a moment to speak to you about the Adobe PSD
format. PSD is not a good format. PSD is not even a bad format. Calling it
such would be an insult to other bad formats, such as PCX or JPEG. No, PSD
48. # Open letters
# Dear maintainer:
#
# Once you are done trying to 'optimize' this routine,
# and have realized what a terrible mistake that was,
# please increment the following counter as a warning
# to the next guy:
#
# total_hours_wasted_here = 42
#
49. # Open letters
# Dear maintainer:
#
# Once you are done trying to 'optimize' this routine,
# and have realized what a terrible mistake that was,
# please increment the following counter as a warning
# to the next guy:
#
# total_hours_wasted_here = 42
#
# Schedule a fix. State the problem.
# OPTIMIZE: or refactor. The problem is....
51. # warnings
# After you run this code, take the day off.
# It won’t finish until tomorrow.
def im_compiling(stop_at=14.hours.from_now)
if stop_at < Time.zone.now
puts "done."
else
print "."
sleep 10
im_compiling stop_at
end
end
52. # warnings
# if it is meant to run long, warn at runtime
def im_compiling(stop_at=nil)
if stop_at.nil?
print “This will take 14 hours. Proceed? (y/n):”
should_continue = STDIN.gets.chomp
if should_continue == “y”
im_compiling 14.hours.from_now
end
elsif stop_at < Time.zone.now
puts "done."
else
print "."
sleep 10
im_compiling stop_at
end
end
53. # warnings
# schedule optimization
# OPTIMIZE: remove the n+1 database calls
def comment_summaries_for_everyone
summaries = []
Person.all.each do |person|
person.posts.each do |post|
post.comments.each do |comment|
summaries << “#{comment.author_name}: #{comment.body}”
end
end
end
summaries
end
54. # dialogs
# This is brilliant!
# Thanks. It’s nap time.
55. # dialogs
# This is brilliant!
# Thanks. It’s nap time.
# email. chat. twitter. phone. how about talk?!?
60. # misleading descriptions
# Returns the standard utility allowance
# based on how many utilities someone pays.
def standard_utility_allowance
324
end
61. # misleading descriptions
# Returns the standard utility allowance
# based on how many utilities someone pays.
def standard_utility_allowance
324
end
# Remove it or investigate what is correct.
def standard_utility_allowance
324
end
62. # stashed code
def standard_utility_allowance
324
# Uncomment this by March 3, 2012 when estimations switch back
#
# case @answers[:utility_allowance]
#
# when 'Pays for Heating or # Cooling or receives MEAP or EUSP'
# 394.0
#
# when "Doesn't pay for heating or cooling but pays two other utilities"
# 239.0
#
# when "Doesn't pay for heating or cooling but pays one utility bill (NOT telephone)"
# @answers[:actual_utility_cost]
#
# when "Pays telephone only"
# 40.0
#
# else
# 0.0
# end
end
63. # stashed code
# write it inline, set a note to clean it up
# FIXME: After March 3, 2012
def standard_utility_allowance
if after_march_3_2012?
case @answers[:utility_allowance]
when 'Pays for Heating or # Cooling or receives MEAP or EUSP'
394.0
when "Doesn't pay for heating or cooling but pays two other utilities"
239.0
when "Doesn't pay for heating or cooling but pays one utility bill (NOT telephone)"
@answers[:actual_utility_cost]
when "Pays telephone only"
40.0
else
0.0
end
else
326
end
end
def after_march_3_2012?
Time.zone.now >= Time.new(2012, 3, 3)
end
64. # deserted code
def standard_utility_allowance
case @answers[:utility_allowance]
when 'Pays for Heating or # Cooling or receives MEAP or EUSP'
394.0
# when "Doesn't pay for heating or cooling but pays two other utilities"
# 239.0
when "Doesn't pay for heating or cooling but pays one utility bill (NOT telephone)"
@answers[:actual_utility_cost]
when "Pays telephone only"
40.0
else
0.0
end
end
65. # deserted code
# remove it. If it passes tests without the code, it is not needed.
def standard_utility_allowance
case @answers[:utility_allowance]
when 'Pays for Heating or # Cooling or receives MEAP or EUSP'
394.0
when "Doesn't pay for heating or cooling but pays one utility bill (NOT telephone)"
@answers[:actual_utility_cost]
when "Pays telephone only"
40.0
else
0.0
end
end
70. # Questions?
# References
Therapeutic Refactoring, Katrina Owen
http://confreaks.com/videos/1071-cascadiaruby2012-therapeutic-refactoring
Chartjunk
http://en.wikipedia.org/wiki/Chartjunk#cite_note-tufte-0
What Do Programmers Really Do Anyway? (aka Part 2 of the Yardstick saga), Peter Hallam
http://blogs.msdn.com/b/peterhal/archive/2006/01/04/509302.aspx
Clean Code, Robert Martin
# My Info
Nate Davis Olds #natedavisolds Benefits Data Trust lead developer
nate@davisolds.com ndavisolds@bdtrust.org www.bdtrust.org
Editor's Notes
\n
\n
RDOC\n\n
YARD\n
\n
- When you become aware of something that needs to be done; just not now\n- Worse than clarifying code if there is no process to return to these problem areas.\n- Acknowledge a problem, stashes it for later fixing, and prevents sidetracks\n\n
In all of these examples, the attention of the comment is outside the scope of the accompanying source code; \n\nin contrast...\n\n\n
in contrast, clarifying comment&#x2019;s attention is directed internally\n\nPOINTS TOWARD THE CODE\n\n\n
EXPLANATIONS\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
JOKES\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
I first heard this\n\n\n\n
I first heard this\n\n\n\n
I first heard this\n\n\n\n
I first heard this\n\n\n\n
DESERTED CODE\n\n\n\n
DESERTED CODE\n\n\n\n
Peter Hallam asserts that coders spend more time reading code than writing code; a lot more.\n\n\n\n
DESERTED CODE\n\n\n\n
DESERTED CODE\n\n\n\n
DESERTED CODE\n\n\n\n
DESERTED CODE\n\n\n\n
EXPLANATIONS\n\n
EXPLANATIONS\n\n
EXPLANATIONS\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
dialogs\nmake sure they get it\n\n\n\n
JOKES\n\n\n\n
JOKES\n\n\n\n
JOKES\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
REDUNDANT\n\n\n\n
This makes sure that it works correctly on time and also scheduled to clean it up.\n\n\n\n