August 2007 Archives

Comparing flog scores of the upcoming Vlad 1.1 + dependencies to capistrano + dependencies:

vlad  = 801.703121839339 + 2852.62383908144
cap   = 11480.3919695285
ratio = cap / vlad
      = 3.141588613252   # <-- zomg! look here!!!

ratio - Math::PI
= -4.04033779499713e-06

target = cap / Math::PI
= 3654.32226116592

target - vlad
= -0.00469975485839313

EDIT: Cleaned up for the terminally ADD. You'd think arithmetic was hard...

ADDED: From Wilson:

"What I'm seeing here is that the endless cycle of creation and destruction cried out for a hero... and Vlad answered the call"

*whew* that was close

| | Comments (0)

rubyconf talk submitted with two minutes to spare...

Flogging the World

| | Comments (1)

Coming out

It is time I come right out and say it...

I am a Ruby Sadist, and I'm OK!

It is true. I like to hurt code. With code I like to hurt systems. It is something I'm good at, I just haven't been able to put it into words very well. Potential employers don't quite understand or empathize when you talk about hurting code, even tho that might be exactly what they're trying to hire you for. They just don't think of it in those terms. To help gather my thoughts, tools, and to communicate my goals more clearly, I've launched ruby.sadi.st. Enjoy...

Flogging the World

Flog 1.1 is out, and with it a lot of enhancements to pointing out code complexity. In particular, it adds full ABC (Assignment, Branches, and Calls) metrics. ABC is a nice, simple whitespace independent way of measuring code that I talked about it in my RubyConf 2005 talk.

Well... I went overboard (again). I flogged every (latest) gem released and poked around. I won't release the full report yet, but here is a bit of a peek:

Statistics:

total # gems      :    1766
total # methods   :  134839
avg methods / gem :   76.35 +/-  170.66
avg flog / project: 1245.47 +/- 3416.56
avg flog / method :   14.06 +/-   32.60

Top 10 Methods per Gem:

 1:       fxruby-1.6.11.gem: 2559 methods,  4.71 +/- 11.33 flog
 2:           bio-1.1.0.gem: 2286 methods, 13.10 +/- 23.22 flog
 3:       puppet-0.23.2.gem: 2044 methods, 15.85 +/- 22.54 flog
 4:       facets-1.8.54.gem: 1962 methods, 11.42 +/- 28.21 flog
 5:        soap4r-1.5.7.gem: 1452 methods, 11.55 +/- 16.59 flog
 6:       bioruby-0.6.4.gem: 1450 methods, 12.04 +/- 22.36 flog
 7:         deplate-0.8.gem: 1426 methods, 14.35 +/- 25.47 flog
 8:           rio-0.4.1.gem: 1291 methods,  6.44 +/- 10.17 flog
 9: activerecord-1.15.3.gem: 1279 methods, 15.12 +/- 26.89 flog
10:   actionpack-1.13.3.gem: 1129 methods, 12.61 +/- 19.95 flog

Most Prolific Developers:

 1:    Daniel J. Berger: 43 projects 11849.9 tot  275.6 avg
 2:       Thomas Sawyer: 43 projects 48329.2 tot 1123.9 avg
 3:          Eric Hodel: 40 projects 36787.0 tot  919.7 avg
 4:       Ara T. Howard: 28 projects 40856.8 tot 1459.2 avg
 5:       Aaron Pfeifer: 19 projects  3733.0 tot  196.5 avg
 6:          Ryan Davis: 18 projects 31990.1 tot 1777.2 avg
 7:      NOT Ryan Davis: 16 projects 15834.9 tot  989.7 avg
 8: Geoffrey Grosenbach: 15 projects  6203.7 tot  413.6 avg
 9:      Erik Hollensbe: 13 projects  2069.0 tot  159.2 avg
10:        Florent Solt: 12 projects  3686.2 tot  307.2 avg

Flog reports the most tortured code in an easy to read pain report. The higher the score, the more pain the code is in.

% ./bin/flog bin/flog
Total score = 128.7

Flog#report: (21)
     4: puts
     2: sort_by
...

Changes:

  • 3 major enhancements:
    • Added assignments and branches and a lot of other stuff. rad.
    • Added process_iter section for DSL style blocks (rake tasks etc).
    • Made Flog usable as a library.
  • 12 minor enhancements:
    • Added -a flag to turn off threshold culling for other tools.
    • Added -s for summarizing the score.
    • Added -v feedback to know what file you're flogging.
    • Added branching penalty so tons of nested conditionals get beat down.
    • Added send (3).
    • Capture and ignore SyntaxErrors from template/generator code. Stupid DHH.
    • Report can now take an IO object.
    • blockargs now penalizes all non-benign forms of blockpass.
    • Added usage to bin/flog. Moved -I processing to bin/flog.
    • Added unpack.rb and updatescores.rb at base level (not installed)
    • Added scoring for blockpass.
    • Converted totals to use distance formula on ABC's.
  • 3 bug fixes:

    • Ran flog on every latest gem available. Found a bunch of problems.
    • Use a stack for both class/module and method accounting.
    • block_args weren't processing the arg
  • http://ruby.sadi.st/

  • http://rubyforge.org/projects/seattlerb

ruby2ruby provides a means of generating pure ruby code easily from ParseTree's Sexps. This makes making dynamic language processors much easier in ruby than ever before.

Changes:

1.1.7 / 2007-08-21

  • 2 major enhancements:
    • Switched to ParseTree's UnifiedRuby... much much cleaner now!
    • Made test_ruby2ruby MUCH more rigorous with circular testing.
  • 5 minor enhancements:
    • Add r2rshow command like parsetreeshow.
    • Add parens for :block nodes as appropriate. May be overzealous.
    • Make SexpAny work with #==.
    • Removed calls to processorstack / caller in favor of self.context.
    • Some style differences, eschew rescue.
  • 6 bug fixes:

    • Fix R2R bug with masgn/argscat.
    • Fixed a bug with new resbody unification.
    • Fixes for changes to pt_testcase.
    • Fixes the rest of the tests under strict sexp checking.
    • Fixed some circular bugs, mostly by hacking them out, wrt operator precidence.
    • Fixed trinary operator.
  • http://seattlerb.rubyforge.org/

  • http://rubyforge.org/projects/seattlerb

ParseTree is a C extension (using RubyInline) that extracts the parse tree for an entire class or a specific method and returns it as a s-expression (aka sexp) using ruby's arrays, strings, symbols, and integers.

As an example:

def conditional1(arg1)
  if arg1 == 0 then
    return 1
  end
  return 0
end

becomes:

[:defn,
  :conditional1,
  [:scope,
   [:block,
    [:args, :arg1],
    [:if,
     [:call, [:lvar, :arg1], :==, [:array, [:lit, 0]]],
     [:return, [:lit, 1]],
     nil],
    [:return, [:lit, 0]]]]]
  • Uses RubyInline, so it just drops in.
  • Includes SexpProcessor and CompositeSexpProcessor.
    • Allows you to write very clean filters.
  • Includes UnifiedRuby, allowing you to automatically rewrite ruby quirks.
  • ParseTree#parsetreefor_string lets you parse arbitrary strings of ruby.
  • Includes parsetreeshow, which lets you quickly snoop code.
    • echo "1+1" | parsetreeshow -f for quick snippet output.
  • Includes parsetreeabc, which lets you get abc metrics on code.
    • abc metrics = numbers of assignments, branches, and calls.
    • whitespace independent metric for method complexity.
  • Includes parsetreedeps, which shows you basic class level dependencies.
  • Does not work on the core classes, as they are not ruby (yet).

Changes:

  • 1 major enhancement:

    • Rewrote parsetreeshow to use parsetreefor_string.
    • parsetreeshow adds -n=node filtering -u unifying, and -s structure-only.
    • parsetreeshow no longer needs -f
  • 4 minor enhancements:

    • Added context stack to SexpProcessor! YAY!!!
    • Enforce type to be symbol in SexpProcessor... just makes life easier.
    • Processing style change mode to UnifiedRuby. Prefer no rescues.
    • Sexp#structure is no longer destructive.
  • 4 bug fixes:

    • Added 1.8.4 compatibility fix.
    • Added args lifting in :defs in UnifiedRuby.
    • Fixed unifying argscat, splat, and a couple other oddities.
    • Added process_call to UnifiedRuby sigh I'm a tard.
  • http://www.zenspider.com/ZSS/Products/ParseTree/

Ruby Inline is an analog to Perl's Inline::C. Out of the box, it allows you to embed C/++ external module code in your ruby script directly. By writing simple builder classes, you can teach how to cope with new languages (fortran, perl, whatever). The code is compiled and run on the fly when needed.

Changes:

3.6.4 / 2007-08-20

When good tests go bad

| | Comments (0)
4:44 : Chad: All heckling was thwarted! YAY!!!
4:44 : Chad: my sissy unit tests aren't so sissy after all ;)
4:47 : Ryan: or that means that your code is so tightly
             coupled that it all falls apart whenever you
             change anything
4:47 : Chad: ass hat

See Also: Notes on Heckle

#rubinius

| | Comments (0)
12:42 @evan : that Array#===
12:42 @evan : what are people thinking?!
12:42 @evan : if you ask that guy what O(n^2) is, he'll just
              poop his pants

"The Ruby Hit Squad has been activated"... that was the message I sent people, and less than 2 weeks later, it happened.

From Saturday, August 4th to Tuesday, August 7th, the Ruby Hit Squad was in full effect. We flew in the prodigious Wilson Bilkovich from Florida, holed ourselves up, and 4 days later we had an all but polished product: Vlad the Deployer.

Severely tired, it took a little while to get the last of it polished off, but we finally got Vlad out the door. We did 94 commits in the first 4 days, and another 42 following to get the release polished up and out the door. It is probably the best that Eric or I have done wrt spit and polish on a 1.0 release, with impl, tests, a fairly complete website, and rdoc. I'm quite happy with it.

I had sooo much fun doing this. I hope that the hit squad can be activated again soon... Right after my nap.

Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync.

Impale your application on the heartless spike of the Deployer.

FEATURES/PROBLEMS:

  • Full deployment automation stack.
  • Supports single server deployment with just 4 variables defined.
  • Very few dependencies. All simple.
  • Uses ssh with your ssh settings already in place.
  • Uses rsync for efficient transfers.
  • Run remote commands on one or more servers.
  • Syncs files to one or more servers.
  • Mix and match local and remote tasks.
  • Built on rake. easy.
  • Compatible with all of your tab completion shell script rake-tastic goodness.
  • Ships with tests that actually pass.
  • Engine is under 500 lines of code.
  • Super uper simple.
  • Does NOT support Windows right now. Coming soon in 1.1.
  • This is 1.0.0... expect rough edges.

Changes:

1.0.0 / 2007-08-04

DESCRIPTION:

Hoe is a simple rake/rubygems helper for project Rakefiles. It generates all the usual tasks for projects including rdoc generation, testing, packaging, and deployment.

Tasks Provided:

  • announce - Generate email announcement file and post to rubyforge.
  • audit - Run ZenTest against the package
  • check_manifest - Verify the manifest
  • clean - Clean up all the extras
  • config_hoe - Create a fresh ~/.hoerc file
  • debug_gem - Show information about the gem.
  • default - Run the default tasks
  • docs - Build the docs HTML Files
  • email - Generate email announcement file.
  • gem - Build the gem file only.
  • install - Install the package. Uses PREFIX and RUBYLIB
  • install_gem - Install the package as a gem
  • multi - Run the test suite using multiruby
  • package - Build all the packages
  • post_blog - Post announcement to blog.
  • post_news - Post announcement to rubyforge.
  • publish_docs - Publish RDoc to RubyForge
  • release - Package and upload the release to rubyforge.
  • ridocs - Generate ri locally for testing
  • test - Run the test suite. Use FILTER to add to the command line.
  • test_deps - Show which test files fail when run alone.
  • uninstall - Uninstall the package.

Changes:

1.3.0 / 2007-08-13

A script which automates a limited set of rubyforge operations.

  • Run 'rubyforge help' for complete usage.
  • Setup: For first time users AND upgrades to 0.4.0:
    • rubyforge setup (deletes your username and password, so run sparingly!)
    • edit ~/.rubyforge/user-config.yml
    • rubyforge config
  • For all rubyforge upgrades, run 'rubyforge config' to ensure you have latest.
  • Don't forget to login! logging in will store a cookie in your .rubyforge directory which expires after a time. always run the login command before any operation that requires authentication, such as uploading a package.

Changes:

0.4.4 / 2007-08-13:

  • New type_id values will merge with extant data. (self-repairing data is Good)
  • Scrape processor_ids, merging in with extant data.
  • Default to "Other" if a file's type is unrecognized.

  • http://rubyforge.org/projects/codeforpeople

Flog reports the most tortured code in an easy to read pain report. The higher the score, the more pain the code is in.

% ./bin/flog bin/flog
Total score = 128.7

Flog#report: (21)
     4: puts
     2: sort_by
...

Changes:

Flog reports the most tortured code in an easy to read pain report. The higher the score, the more pain the code is in.

% ./bin/flog bin/flog
Total score = 128.7

Flog#report: (21)
     4: puts
     2: sort_by
...

Changes:

ParseTree is a C extension (using RubyInline) that extracts the parse tree for an entire class or a specific method and returns it as a s-expression (aka sexp) using ruby's arrays, strings, symbols, and integers.

As an example:

def conditional1(arg1)
  if arg1 == 0 then
    return 1
  end
  return 0
end

becomes:

[:defn,
  :conditional1,
  [:scope,
   [:block,
    [:args, :arg1],
    [:if,
     [:call, [:lvar, :arg1], :==, [:array, [:lit, 0]]],
     [:return, [:lit, 1]],
     nil],
    [:return, [:lit, 0]]]]]
  • Uses RubyInline, so it just drops in.
  • Includes SexpProcessor and CompositeSexpProcessor.
    • Allows you to write very clean filters.
  • Includes UnifiedRuby, allowing you to automatically rewrite ruby quirks.
  • ParseTree#parse_tree_for_string lets you parse arbitrary strings of ruby.
  • Includes parse_tree_show, which lets you quickly snoop code.
    • echo "1+1" | parse_tree_show -f for quick snippet output.
  • Includes parse_tree_abc, which lets you get abc metrics on code.
    • abc metrics = numbers of assignments, branches, and calls.
    • whitespace independent metric for method complexity.
  • Includes parse_tree_deps, which shows you basic class level dependencies.
  • Does not work on the core classes, as they are not ruby (yet).

Changes:

  • 2 major enhancements:

    • Rewrite methods completely rewritten. Rewriters:
    • are no longer recursive.
    • are no longer required to empty the sexp coming in.
    • are depth first, so rewriter gets passed everything already normalized.
    • keep rewriting until type doesn't change.
    • are magical goodness.
    • Added UnifiedRuby module to aid others in writing clean SexpProcessors:
    • bmethod/dmethod/fbody unified with defn
    • fcall/vcall unified with call
    • resbody unified with itself (lots of different forms)
  • 5 minor enhancements:

    • Add #modules to Module.
    • Add Sexp::for shortcut for Sexp.from_array ParseTree.translate(...).
    • Add parens for :block nodes as appropriate. May be overzealous.
    • Made add_to_parse_tree global for reuse by other C extensions.
    • Made test_ruby2ruby MUCH more rigorous with circular testing.
  • 6 bug fixes:

    • Added $TESTING = true to pt_testcase.rb. OOPS!
    • Fixed some circular bugs, mostly by hacking them out, wrt operator precidence.
    • Fixed splat arg processing when arg has no name.
    • Fixed trinary operator.
    • Fixed BMETHOD with no arguments.
    • Removed hacky "self." thing for defs at top level PT use.
  • http://www.zenspider.com/ZSS/Products/ParseTree/

Flog reports the most tortured code in an easy to read pain report. The higher the score, the more pain the code is in.

% ./bin/flog bin/flog
Total score = 128.7

Flog#report: (21)
     4: puts
     2: sort_by
...

Changes:

1.0.0 / 2007-08-01