My Great Lakes Ruby Bash Notes
Ann Arbor, Michigan, October 10, 2008
Predicting The Future: A Perspectives on Ruby and Rails – Winston Tsang (9:10am)
Be Sensitive to areas from which change is emerging. Be aware of what is going on around you.
A Look into the Past at Problems People Had
- Packages (Jars, RPM’s)- Ruby’s Gems solved the problem, plus documentation using ‘gem server’
- Testing (required immense configuration) – Rails? Tests are baked right in. autotest takes it to the next level of automation
- Deployment – Capistrano solves it for rails apps
“The future is here, it’s just not evenly distributed yet.” – William Gibson
Using Active Scaffold – Joseph Faisal Nusairat (9:30am)
- Production Quality Scaffolding
- Ajaxified/Restful/Sexy
- 3rd Party Plugins Available
- Add the active_scaffold plugin from the git repo
- ”<%= active_scaffold_includes %>” in your layout
active_scaffold :keyword do |conf|
conf.create.columns = [:name, :description]
conf.update.columns = [:name, :description]
conf.list.columns = [:name, :description]
conf.create.link.label = "Add Keyword"
conf.actions.exclude :show
end
- can use a global config to ignore columns
- observes validations from ActiveRecord
- search comes for free on string fields
- can add live searching with a config
- can add new children (categories, keywords)
- can get prettier calendars as plugins
- easy to add column sorting
- Useful for admin site areas, less so for front-end customer-facing areas
- Tempo on integrallis.com is an example in use
Hacking the Mid-End: Advanced Rails UI Techniques – Michael Bleigh (10:00am)
- Intridia => [:crowd_sound, :media_plug, :present_ly]
Define Mid-End
- MC – Backend developers
- V – Designers and Frontend Developers
- MVC+I (I is for Interaction) => Mid-End Developer is all about Abstraction
- Delivering Smart Partials to the Front-End developer
- Deliver a Smart Helper to the Back-End Developer
- Get XHTML/CSS from the Front-End Developer
- Get App/Structure from the Back-End Developer
Mid End Should Be
- Fast – perception is key, must feel fast
- Accessible – to as many people as possible (screen readers, color contrast) and to Multiple Devices
- Unobtrusive Javascript is an automatic best practice – rails is imperfect here
- Intuitive – Leverage User Expectations
- is this a web app or a desktop app on the web? No wrong choice, but web apps are right.
- Responsive – immediate or near-immediate feedback after an action that action is underway or completed
Solving Midend Problems
- Helpers – Block-Accepting
- Partials
- jQuery
- LowPro (makes prototype less obtrusive)
The Approach
- build it without js
- abstract UI into helpers and partials
- add unobtrusive javascript
- Avoid the “Unknowing, What’s Going On” Stage
- Add generate.html.erb (our old show.html.erb)
- Show action becomes – “TPS Reports May Take Up to 10 seconds to Generate”
DelayedLoader = $.klass({
initialize.function() {
link = this.element.find('a.continue');
this.url = link.attr('href');
link.replaceWith('< image of spinner >');
var element = this.element;
$.get(this.url, function(data) {
element.html = data;
});
}
});
- pre-load all tabs for js-users, then show content as necessary.
- remove ‘current’ class from non-current tab names
Problem: Updating Parts of a Page in Ajax, But not Updating the “Time Ago” for earlier entries
- time ago in words for js
- add the actual time as a title
- reparse times from titles using Date.update_relative_times()
Usability on Rails: Tips & Tricks for Creating Passionate Users – Larry Karnowski (11:00am)
Don’t Test Your Views
- Treat views as Data, not Code
- Extract all code from view for testing
- Validate Your Views for Testing
- Test Your Helpers – ActionView::TestCase
Tarantula – spiders your app using webrick in memory
- login
- follow_redirect!
- tarantula_crawl(self) – fuzzy spider – follows links and hits forms with fuzzy data
- safe_erb – disallows potentially-tainted strings
- unit_controller – narrows scope of testing to the controller only
Into the Middle of Things (In Media Res)
- Customers are not at the beginning of the process. By the time we meet them, they have a problem.
- They don’t love software, They want to kick ass.
- Make them feel empowered.
Flashback! to the beginning
- What do we need to build?
- Start with a User Interview
- Learn the user’s language
- stay agile
- be aware of user needs vs. their supervisors/employers (if I was talking to a real user, this will be a better app)
- What is it going to look like?
- Start with pen & paper sketches – different part of the brain (cheap, easy, permission to contribute is implicit)
- Find the best user experience first
- learn the intent of the app
- don’t consider implementation initially
- 3-4 wireframes => it takes a lot of bad ideas to get to one good one
- Adjust scope to reality
- OmniGraffle
- HTML/CSS Mockups
- user serve plus erb
The Engineer’s Fallacy – People are not logical, they are emotional. Engineers don’t know that.
User Behavior
- Data Smells
- Non-Linear Scanning of Pages
- Ad Blindness
- Technology Myths & Superstitions
Agile User Testing – Coming Soon
- forget big labs, video, audio
- cheap, cheap, cheap
- try to get real users (office manager is more computer savvy), but grade on a curve
- neighbors, spouses, Mom
- need three testers, but rinse & repeat
Keep vocabulary consistent across multiple uses inside the app – same word – don’t use synonyms
“Get It” Testing
- earlier
- sketches wireframes, mockups
- “i spy”, not “show & tell” – tell me what you see.
Think aloud testing
- determine use cases
- emphasize that software is being tested, not the user
- after every iteration if possible, but once a month is great
Quick Tips
- show users where they are
- mileposts
- bread crumbs
- reduce memory load (we have 2x-10x the memory they do)
- don’t leave ‘em wondering
- NEVER throw away your user’s work
Good Error Messages
- context aware
- Rails validation error messages are not context aware (being in the models) and are cumbersome with associations
- plain english
- suggest their own fix
Wicked Messenger – Creates a Hierarchy of Error Messages
Help Doesn’t
- people don’t read until after they screw up
- use JIT help
We aren’t there to help when the big battle is underway. We are the supernatural aid to the hero.
“Don’t make me think” – Steve Krug “The Back of the Napkin” – Dan Roam
Boxesandarrows.com adaptivepath.com codinghorrow.com
github.com/lawjoskar
HAML => “I don’t want input from a designer, ever.”
Playing it Safe – How to write library friendly code in Ruby – Jim Weirich (1:00pm) (or How to Avoid Being Leeroy Jenkins)
Playing well with Others – Does it Matter? Application (No) vs. Library (Yes)
“At least I have chicken.”—Leeroy Jenkins
Tips for Playing it Safe
- protect against accidental problems
- Use Namespaces (node => put it in a module)
- Choose Project Name Carefully (check gems, github, RubyForge and don’t duplicate those)
- Avoid Top Level Functions and Constants (put them in the module)
- Avoid Modifying Existing Classes – Prefer adding over modifying (adding rake_dup in kernel instead of modifying Kernel::dup),
- When adding use project scoped names (scoped with the “rake” name to reduce conflicts)
- you be nice and check for conflicts – “unless instance_methods.include? ‘ext’” – ask first, then add
- Selector Namespaces (coming in Ruby 2.0 per Matz)
Replacing Behavior
- allow backwards compatibility
- const_missing to return Rake::Task and give you a warning
Hooking Tips
- go back and invoke the original const_missing – chain your hook behavior
- only handle your special cases
- limit the scope of your hook, esp. for method_missing (handle your methods then hand it up the chain)
kirby problem vs. whiny_nils => make it better than the existing method
Require Hooks
- ruby_gems overrides require
- try original require
- adds a rescue on the LoadError to search for the gem, adds it to the load path
- try original require and raise the original require’s error if it still fails
Preserve the Original Behavior
Understand and Obey Contracts between Callers and libraries (Design by Contract)
- pre-condition: What Must be true before a method is called (for Math.sqrt, n >= 0)
- post-condition: What Must be true after a method is called (for Math.sqrt, (Result*Result-n).abs < 0.001)
- New Behavior Added Must have the same or weaker precondition
- New Behavior Added Must have the same or stronger postcondition (ReallyAccurate.sqrt(n))
- Bertrand Meyer => Require no more. Promise no less.
Summary
- Be Polite with Global Resources
- Respect and Obey Contracts when Duck Typing
New Features in Test::Unit 2.0 – Daniel Berger (2:00pm)
require 'rubygems'
gem 'test-unit'
require 'test/unit'
- assert_true, assert_false, assert_boolean
- omit, omit_if, omit_unless => skips a test good for platform-specific , omissions are tracked separately in the output
- pend – a todo with annoyance
- notify – maybe as a test debugger, but it is tracked
- startup and shutdown – analogous to setup and teardown, run once per test case
def self.startup
# anything you need to only do one time
end
def self.shutdown
# anything you need to only do one time
end
- multiple setup & teardown – organize setups better if they start to get too long
setup # first
def foo
end
setup # second
def foo_2
end
- better diff output
- priority mode reduced test time – runs all failed tests plus 50% of successful ones (priority :must and it will always run)
- colorized output
Behavior Driven Development with Cucumber – Brandon Keepers (2:30pm)
- Language is a barrier between developers and clients
- User Stories Capture Intent of the Feature
- why, who then feature
- Quality: works as expected
- After gaining confidence, Testing can become part of the design process, then Specifying Behavior Completes the Evolution
Cucumber
- rbehave, then rspec story runner, then cucumber
- runs in ruby but can be used to test other web apps
- is a rake file to run the features
Feature (top level story): Manage Companies
In order to keep track of companies
a user
should be able to manage companies
Scenario: Add a New Company
Given I am logged in
When I create a new company named Acme
Then I should see that a company named Acme exists
- Don’t implement login as the first feature
Into the Limelight: An Introduction to a Ruby Rich Client Framework – Paul Pagel (3:15pm)
Metawhat? A look into the mysterious metaclass Brandon Dimcheff (3:45pm)
- Metaclass, Singleton Class, Eigenclass, Virtual Class
- an object is a pointer to its class
- a class has a collection of methods and a super pointer
method dispatch
- dereference my class pointer
- check the methods table for my method
- call the method or move on to the superclass and search there if it doesn’t exist
instance-specific values causes a singleton class to be created
a metaclass is a singleton class of a class
all classes have metaclasses
On Diversification
I’ve been all over the map on diversification. Initially, I was in mutual funds and tracking stocks. In downward spirals, they all gravitated lower. Breadth in a bear market was a guaranteed way to lose money. It seems like individual equities are the only thing that escaped the downdrafts.
Lately, I have been playing for quick pops – looking for a big move in 48-72 hours, usually around earnings or extraordinary events. When I find one that looks promising, I go big and try to maximize the profit generated.
The guys that send the checks from my employer to my 401K account have noticed the same trend in my investing. They are none too keen on my style, but they can’t knock my results.
View archives for October 2008.


