class Flog
Constants
- BRANCHING
Names of nodes that branch.
- DEFAULT_THRESHOLD
Cut off point where the report should stop unless –all given.
- OTHER_SCORES
Various non-call constructs
- SCORES
The scoring system hash. Maps node type to score.
Public Class Methods
Creates a new Flog
instance with options
.
# File lib/flog.rb, line 233 def initialize option = {} super() @option = option @mass = {} @parser = nil @threshold = option[:threshold] || DEFAULT_THRESHOLD self.auto_shift_type = true self.reset end
Public Instance Methods
Add a score to the tally. Score can be predetermined or looked up automatically. Uses multiplier for additional spankings. Spankings!
# File lib/flog.rb, line 112 def add_to_score name, score = OTHER_SCORES[name] return if option[:methods] and method_stack.empty? @calls[signature][name] += score * @multiplier end
really?
# File lib/flog.rb, line 120 def average return 0 if calls.size == 0 total_score / calls.size end
Calculates classes and methods scores.
# File lib/flog.rb, line 128 def calculate each_by_score threshold do |class_method, score, call_list| klass = class_method.scan(/.+(?=#|::)/).first method_scores[klass] << [class_method, score] scores[klass] += score end end
Calculates the total score and populates @totals.
# File lib/flog.rb, line 306 def calculate_total_scores return if @totals @total_score = 0 @totals = Hash.new(0) calls.each do |meth, tally| score = score_method(tally) @totals[meth] = score @total_score += score end end
Returns true if the form looks like a “DSL” construct.
task :blah do ... end => s(:iter, s(:call, nil, :task, s(:lit, :blah)), ...)
# File lib/flog.rb, line 143 def dsl_name? args return false unless args and not args.empty? first_arg = args.first first_arg = first_arg[1] if first_arg[0] == :hash [:lit, :str].include? first_arg[0] and first_arg[1] end
Iterate over the calls sorted (descending) by score.
# File lib/flog.rb, line 155 def each_by_score max = nil current = 0 calls.sort_by { |k,v| -totals[k] }.each do |class_method, call_list| score = totals[class_method] yield class_method, score, call_list current += score break if max and current >= max end end
Flog
the given files. Deals with “-”, and syntax errors.
Not as smart as FlogCLI's flog
method as it doesn't traverse dirs. Use PathExpander to expand dirs into files.
# File lib/flog.rb, line 174 def flog(*files) files.each do |file| next unless file == '-' or File.readable? file ruby = file == '-' ? $stdin.read : File.binread(file) flog_ruby ruby, file end calculate_total_scores end
Flog
the given ruby source, optionally using file to provide paths for methods. Smart. Handles syntax errors and timeouts so you don't have to.
# File lib/flog.rb, line 191 def flog_ruby ruby, file="-", timeout = 10 flog_ruby! ruby, file, timeout rescue Timeout::Error warn "TIMEOUT parsing #{file}. Skipping." rescue RubyParser::SyntaxError, Racc::ParseError => e q = option[:quiet] if e.inspect =~ /<\%|%\>/ or ruby =~ /<\%|%\>/ then return if q warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}" warn "\n...stupid lemmings and their bad erb templates... skipping" else warn "ERROR: parsing ruby file #{file}" unless q unless option[:continue] then warn "ERROR! Aborting. You may want to run with --continue." raise e end return if q warn "%s: %s at:\n %s" % [e.class, e.message.strip, e.backtrace.first(5).join("\n ")] end end
Flog
the given ruby source, optionally using file to provide paths for methods. Does not handle timeouts or syntax errors. See flog_ruby
.
# File lib/flog.rb, line 217 def flog_ruby! ruby, file="-", timeout = 10 @parser = (option[:parser] || RubyParser).new warn "** flogging #{file}" if option[:verbose] ast = @parser.process ruby, file, timeout return unless ast mass[file] = ast.mass process ast end
Returns the method/score pair of the maximum score.
# File lib/flog.rb, line 246 def max_method totals.max_by { |_, score| score } end
Returns the maximum score for a single method. Used for FlogTask
.
# File lib/flog.rb, line 253 def max_score max_method.last end
For the duration of the block the complexity factor is increased by bonus This allows the complexity of sub-expressions to be influenced by the expressions in which they are found. Yields 42 to the supplied block.
# File lib/flog.rb, line 263 def penalize_by bonus @multiplier += bonus yield @multiplier -= bonus end
Reset score data
# File lib/flog.rb, line 272 def reset @totals = @total_score = nil @multiplier = 1.0 @calls = Hash.new { |h,k| h[k] = Hash.new 0 } @method_scores = Hash.new { |h,k| h[k] = [] } @scores = Hash.new 0 method_locations.clear end
Compute the distance formula for a given tally
# File lib/flog.rb, line 284 def score_method(tally) a, b, c = 0, 0, 0 tally.each do |cat, score| case cat when :assignment then a += score when :branch then b += score else c += score end end Math.sqrt(a*a + b*b + c*c) end
Final threshold that is used for report
# File lib/flog.rb, line 299 def threshold option[:all] ? nil : total_score * @threshold end