Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation is counted #23

Open
Mange opened this issue Oct 21, 2013 · 2 comments
Open

Documentation is counted #23

Mange opened this issue Oct 21, 2013 · 2 comments

Comments

@Mange
Copy link

Mange commented Oct 21, 2013

Documentation to classes and methods are counted. I could agree that comments within methods should be counted since they add to the mental burden of reading that method.

Comments on top of methods, however, should not penalized since they are there to document the library, and that is a good thing. Incentivizing people to remove comments to get "better stats" is scary.

I propose that you re-use the "method line" calculations to calculate the lines of every method inside the class and then adding them up.

# This is awesome documentation. It is not counted since it's before the class begins.
class Foo
  # This is awesome documentation again.
  # These lines are counted
  def initialize
    puts "Hello"
    puts "World"
  end

  # Go to the bar!
  def bar
    puts "Bar"
  end

  # Documentation
  def baz() puts "Baz" end
end

This should count as 8 lines (or 10 if you want to count blank lines), not 14 lines:

  • Foo#initialize = 2 + 2 lines
  • Foo#bar = 1 + 2 lines
  • Foo#baz = 1 line

Generally, the formula would be: (multiline methods) * 2 + (sum of multiline bodies) + (single line methods)

Or, in Ruby (pseudo code):

class ClassStatistics
  def lines
    multiline_methods.size * 2 + multiline_methods.map(&:lines) + singleline_methods.size
  end
end

Another method would be to discard the comments at the current indentation level inside the class. Just remember that some people follow this, older, convention:

class Foo
  def bar
  end

  private
    def baz
    end
end
@makaroni4
Copy link
Owner

@Mange I am not that class_lines == methods_lines because that way we will miss inline class code.

I think that it would be better to skip comments at all. Do you know any good tool to remove comments? (I think it should be crazy regexp, we should look for it in rdoc gem for example)

@Mange
Copy link
Author

Mange commented Oct 22, 2013

Well, we could fix 80% of cases by just filtering lines that match /\A\s*#/, honestly. Fixing =begin and =end comments would be easier to fix with iteration:

filtered_lines = []
state = :normal
lines.each do |line|
  case line
  when "=begin\n"
    state = :comment
  when "=end\n"
    if state == :comment
      state = :normal
    else
      filtered_lines << line
    end
  else
    filtered_lines << line
  end
end

Alternatively, one could filter the entire file first:

comment_regexp = /
  # =begin/=end blocks
  (
    ^=begin$
    .*?
    ^=end$
  )
  |
  # line comments
  (
    \s*\#.*?$
  )
/xm
filtered_code = code.gsub(comment_regexp, '')

(Interactive example: http://rubular.com/r/NT3fK4nWx8)
This should remove all comments in 95%+ of cases. Problems would arise if users used "=begin" and/or "#" inside multiline strings or heredocs:

evil_string = "yeah
# I hate people writing clever regexp
# Take THAT!"

puts <<-FOO
=begin
This will not be counted. lol.
=end
FOO

The only way around that is to use the parser...

require 'ripper'
Ripper.lex("=begin\n=end\nfoo #bar\n#baz") # =>
 # [[[1, 0], :on_embdoc_beg, "=begin\n"], [[2, 0], :on_embdoc_end, "=end\n"], [[3, 0], :on_ident, "foo"], [[3, 3], :on_sp, " "], [[3, 4], :on_comment, "#bar\n"], [[4, 0], :on_comment, "#baz"]]

Ripper.sexp("=begin\n=end\nfoo #bar\n#baz") # =>
# [:program, [[:vcall, [:@ident, "foo", [3, 0]]]]]

Good luck with that! :-P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants