Gathering Statistics About Your Code

Credit: Stefan Lang

Problem

You want to gather statistics about your Ruby project, like the total number of lines of code.

Solution

Heres a class that parses Ruby source files and gathers statistics. Put this in scriptlines.rb in your projects top-level directory.

	# scriptlines.rb
	# A ScriptLines instance analyses a Ruby script and maintains
	# counters for the total number of lines, lines of 
code, etc.
	class ScriptLines

	 attr_reader :name
	 attr_accessor :bytes, :lines, :lines_of_code, :comment_lines

	 LINE_FORMAT = \%8s %8s %8s %8s %s

	 def self.headline
	 sprintf LINE_FORMAT, "BYTES", "LINES", "LOC", "COMMENT", "FILE"
	 end

	 # The 
ame argument is usually a filename
	 def initialize(name)
	 @name = name
	 @bytes = 0
	 @lines = 0 # total number of lines
	 @lines_of_code = 0
	 @comment_lines = 0
	 end

	 # Iterates over all the lines in io (io might be a file or a
	 # string), analyses them and appropriately increases the counter
	 # attributes.
	 def read(io)
	 in_multiline_comment = false
	 io.each { |line|
	 @lines += 1
	 @bytes += line.size
	 case line
	 when /^=begin(s|$)/
	 in_multiline_comment = true
	 @comment_lines += 1
	 when /^=end(s|$)/:
	 @comment_lines += 1
	 in_multiline_comment = false
	 when /^s*#/
	 @comment_lines += 1
	 when /^s*$/
	 # empty/whitespace only line
	 else
	 if in_multiline_comment
	 @comment_lines += 1
	 else
	 @lines_of_code += 1
	 end
	 end
	 }
	 end

	 # Get a new ScriptLines instance whose counters hold the
	 # sum of self and other.
	 def +(other)
	 sum = self.dup
	 sum.bytes += other.bytes
	 sum.lines += other.lines
	 sum.lines_of_ 
code += other.lines_of_code
	 sum.comment_lines += other.comment_lines
	 sum
	 end

	 # Get a formatted string containing all counter numbers and the
	 # name of this instance.
	 def to_s
	 sprintf LINE_FORMAT,
	 @bytes, @lines, @lines_of_code, @comment_lines, @name
	 end
	end

To tie the class into your build system, give your Rakefile a stats task like the following. This task assumes that the Rakefile and scriptlines.rb are in the same directory:

	task stats do
	 require scriptlines

	 files = FileList[lib/**/*.rb]

	 puts ScriptLines.headline
	 sum = ScriptLines.new("TOTAL (#{files.size} file(s))")

	 # Print stats for each file.
	 files.each do |fn|
	 File.open(fn) do |file|
	 script_lines = ScriptLines.new(fn)
	 script_lines.read(file)
	 sum += script_lines
	 puts script_lines
	 end
	 end

	 # Print total stats.
	 puts sum
	end

Discussion

ScriptLines performs a very basic parsing of Ruby code: it divides a source file into blank lines, comment lines, and lines containing Ruby code. If you want more detailed information, you can include each file and get more information about the defined classes and methods with reflection or an extension like Parse Tree.

Invoke the stats task to run all the Ruby scripts beneath your lib/ directory through ScriptLines. The following example output is for the highline library:

	$ rake stats
	(in /usr/local/lib/ruby/gems/1.8/gems/highline-1.0.1)
	BYTES LINES LOC COMMENT FILE
	18626 617 360 196 lib/highline.rb
	12745 375 168 181 lib/highline/menu.rb
	15760 430 181 227 lib/highline/question.rb
	801 25 7 14 lib/highline/import.rb
	47932 1447 716 618 TOTAL (4 scripts)

BYTES is the file size in bytes, LINES the number of total lines in each file, LOC stands for "Lines Of Code," and COMMENT is the number of comment-only lines.

These simple metrics are good for gauging the complexity of a project, but don use them as a measure of day-to-day progress. Complexity is not the same as progress, and a good days work might consist of replacing a hundred lines of code with ten.

See Also

  • ri Kernel#sprintf
  • The RDoc documentation for Rakes FileList class (http://rake.rubyforge.org/classes/Rake/FileList.html)
  • The ParseTree extension (http://rubyforge.org/projects/parsetree/)


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net