polishing ruby by ryan davis

SDForum SubEthaEdit Notes

Published 2006-04-24 @ 15:36

Tagged ruby, rails

*** Shared notes, join in!!!

Tim Burks, newbie ruby hacker Colin Charles, MySQL AB Ryan Davis, Seattle.rb Chad Fowler, butthead Michael Granger, Portland Eric Hodel, Seattle.rb Adam Keys, Dallas.rb Deirdre Saoirse Moen, virtual.net

** intro… boring…

I wonder if it would have been boring if you didn’t know anything about the Ruby world or the whole SIG/user group idea? Why wouldn’t you know about that, though eh?

** Adam Keys

It is ruby’s aesthetic that makes it beautiful and fun to use, and that is what distinguishes it from other languages.

blocks make me feel smart, and change my programming in other languages

“Programming by intuition” - POLS

def duck?(obj) self.respond_to? :walk_like_duck and self.respond_to? :talk_like_duck end # should be on Object w/o arg

Really, that example should be:

def do_duck_things( obj ) obj.walk_like_a_duck end or if you’re paranoid:

def do_duck_things( obj ) raise ArgumentError, “can’t convert to a Duck” unless obj.respond_to?( :walk_like_a_duck ) obj.walk_like_a_duck end but you should just be writing a test for duckishness anyway, eh? (for those of us who speak Canadian-ese)

“Ruby is Lisp minus macros plus conveniences.”

Rails: we all say poe-tay-toe - homogeneous vocabulary

C++ is opinionated software also.

Transcontinental Railroad Pattern - really successful applications work from top-down and bottom-up and meet in the middle.

Rails lets you talk in terms of the methods in rails and doesn’t sound like gibberish like lots of other languages/frameworks.

“Unwritten software is the easiest to maintain” – Ruby allows more to be written with less code.

Rails is presented as an example of goodness. What can we take from rails into other domains? Are there good examples from rails that aren’t already in ruby?… one example: as a framework, rails stays deliberately low-level (no components) another: tests are built into the framework [but not particularly well - use Test::Rails]

Code can tell you when you botched an earlier assumption. Gives you design feedback.

Enslaving computers – I think this is a really good point. We often spend a lot of time thinking about elaborate algorithms, but software designed by phd’s usually enslaves users by being difficult to use.

Edward Sapir – language and thought are intertwined. It is difficult to have a thought if it cannot be concisely expressed in language. ‘the “real world” is to a large extent unconsciously built up on the language habits of the group’

** Ryan Davis - Eric was lazy and didn’t take notes on my talk since he has access to my slides, but he did take notes for the entire Q&A.

*** Questions

How do you start? - Story cards

How to get to TDD when we all work in big legacy projects? - “Working effectively with legacy code” - Michael Feathers - excellent book

Speed? - “I kick ass” [and I’m available for hire] - “I use TDD” - No, there really isn’t a “small enough” project to not use TDD unless I’m never going to use it again past writing it (ie, learning/R&D)

BDD? - “Ask Steven Baker”

More incentive to test in dynamically typed languages? - static typing isn’t le - “Less incentive, works most of the time”

Where does it fall over? - Don’t have Smalltalk’s tools - GED: Breakpoint drops you into irb

Refactoring tools for ruby? - what will it be like in 2-3 years - good, thanks to: - ParseTree - Grammarians

ZenTest and RadRails? - Yes

multiruby - Multiple platforms? - yes

Need functional tests? - Not really

IDEs? - Dunno

Testing and team sizes? - smaller teams

Testing and team responsibilities? - need auditing process for your code still - involve your client more

Security testing? - In your regular tests

Ruby projects? - ~1500 rubyforge projects - ~ 1TB/month download traffic - ~ 450k hits/day

How does it scale? More than 20 people? 50? - “I like small better” - “In a big project, mine met targets” - “Our code has still held up” - 4-5 in US, 10-15 in QA - “Communications becomes important in large projects, look at the tests, anything you do should leave it as functional as it was” -ged - “Add-on to other practices”

How does this affect traditional QA? - “Can’t test aesthetics, can’t test usability, still need them”

Code coverage? - “Haven’t used them” - rcov, C thingy - Law of diminishing gains, 90% coverage with 10% code, typically don’t need it for my projects–but I don’t work on million dollar projects

Load and stress testing - Separate phase, more clean room, uses higher-level use cases - Big measure, weekly checkpoint - Test for instrumentation in unit tests

What if my tests run for an hour? - Your tests are broken, so you’re not light and agile - Mock things so you don’t hit the hardware (he was working against custom devices)

Are unit tests good for integration tests? - Not for system/integration testing, want fast feedback - “Start at acceptance tests, when they pass, go home. Stairstep top-down acceptance, functional, units” - ged - ged said something to the effect of write out your integration tests, and then functional tests to ensure your integration tests, and then your unit tests to ensure your functional tests. ryan called it “top down testing” compared to “bottom up” unit testing. - your integration tests say that scenario 1 & 2 & 3 need to work back to back, your functional tests assert that those scenarios are correct in isolation, unit tests drive that down to the model level.

DHH vs TDD w/ ZenTest - We argue about how much testing should be done.

No peekie TDD - paper and crayon! - Type of data - How it functions - Started testing - models - functional

** Hal Fulton

Interfacing Ruby with Oracle

He’s not a database or Oracle guy (not being an Oracle guy is a great thing) The bowels of Oracle are kinda painful He’s working with a 4 TB data warehouse, 100M transactions/day (telecom) Various Ruby drivers for Oracle “If you’re lucky enough to be unfamiliar with OCI” - exactly (Can you tell AKK hates Oracle yet?) OCI8 interface is layered: - high level Ruby interface - low level that wraps OCI

So using the low level API reads just like any other program using OCI

…shoddy WiFi…

A DBI driver for OCI8 exists ActiveRecord driver exists for OCI8 too

There might be a Ruby/DL version of the library so that an extension is unnecessary. There is also an Og wrapper.

You can do PL/SQL if you want. There are ways to handle ‘out’ parameters. No stored procedures right now. At least not in Ruby and OCI8, but its on the plate.

** Rich Kilmer - The Contract

*** Intro

blah blah background blah blah - lots of stuff for ruby

ruby flash

flash based UI connected to ruby flash has a socket API, so does ruby alph is an object broker between the two ActionScript is a quasi JS 2.0 language ruby can call through alph to ActionScript in flash

*** The Setup

“beware friends inviting you to meetings”

This is the most impossible thing to take notes on… it is a story, not a presentation.

*** Prototype

coronet_mission “CW 314” do coronet_leg 2 do … end end

DSL made domain model correct - Sergeants said “oh no, we do it that way, not this way”. Domain understanding was incomplete.

rule_attr_accessor - automatically notifies somebody of changes

“DSLs help me think about it”

*** Chad Fowler - Rails 1.1 changes

Languages evolve to: + crystalize communication + Mimic (perceived) Sophistication + Help lazy people be lazy - glottal stop, “wot” “ain’t” etc

Evolution of Rails is not about Beauty or Productivity. It is about communication.

Rails 1.1 is an evolutionary step, made by “speakers” not “designers”.

Join Models - has_and_belongs_to_many

class Subscription belongs_to :redaer belongs_to :magazine end

class Reader has_many :subscriptions has_many :magazines, :through => :subscriptions end

class Magazine has_many :subscriptions has_many :readers, :through => :subscriptions end

chad = Reader.find_by_name(“Chad”) mag = Magazine.create(…) chad.subscriptions.create(:magazine => mag) chad.magazines.include? mag # => true

*** Polymorphic Associations

People has_many Addresses Companies has_many Addresses

both people and companies have many addresses

class Person has_many :addresses, :as => :addressable end

class Company has_many :addresses, :as => :addressable end

class Address belongs_to :addressable, :polymorphic => true end

*** Testing Across Controllers aka Integration Tests

def test_blah_process get “/login” # uses routes to get controllers automatically … get “/signup” … end

Rails Console app thingy

script/console » app.get ‘/login’ => 200 » app.response.body.grep /title/ =>[”

foo”]

lots of calculation stuff - boring really but nice to have

Person.find_by_name(“Adam”).ratings.average(:value) # => 2.0 # one query? - test

*** Scoping:

Person.find(:all, :conditions => [‘account_id = ?’, account]) # every time

vs:

Person.with_scope(:find => {:conditions => [“account_id = ?”, account_id]}) do … end

*** Deep Joins:

Person.find(:all, :include => [:company => [:products => :prices]])

RJS - effects, prototype, javascript, etc.

page[:time_updated].update Time.now.to_s page[:time_updated].visualEffect :shake page.delay(3.seconds) do page.alert @rails_version; end …

with custom builders!! woot

*** Simple Services

no comprendo… talk to chad at break

what language do you speak?

extend rails to speak your language

roster_for :students, :based_od => last_name do @class_year = params[:class_year] @roster.action = ‘general’ end

** Eric Hodel - Distributed Ruby

Ryan was lazy and didn’t take any notes because he has access to Eric’s slides.

*** metaprogramming - David Pollak

Really I can’t track this. I can’t figure out what he is saying and I hope it is just my brain. the day is long.

** Steven Baker - BDD

Test is the wrong word, there is nothing to test at the beginning.

Sapir-Worph

BDD = specifying the behavior

“Changing the way you think about TDD”

“If you’re doing it right [BDD] is exactly what you’ve been doing [with Test::Unit].”

@expected.should.be.false .should.be. #…

** Scaling Rails

nattering…

Hosts parts of pragprog.com for free.

Joyent needd an infrastructure for “diverse” things - web stuff, mail stuff, database stuff, file stuff

Gets bunches of email asking the same questions: - Is ruby stable? - Long term development? - How can I switch from Ruby to X? - Is RoR the right platform for a large-scale app?

What is ‘it’? - A ‘large scale’ application? - Do you really have a big one? - What is an ‘intensive’ application? - What is an ‘enterprise’ application?

We’ve been doing ‘it’ with: - Perl, PHP, Python’ Java Does language really matter to the systems people?

Reality check: -> OK -> Not a problem -> I’ll need $325k tomorrow and $18.5k month Ok

More than just a language, need a framework for the whole thing.

Do you work with a language and framework that you love?

Does whitespace matter?

You should worry about scaling.

What does it mean? - Can you go start-up -> mid sized without going out of business? - Can you do what you gotta do without having your program cut? - Will your app run on a phone?

What is the slowest part? - The connect you’re paying for - transactions/second

Can you push 1Gbps (12.5MB/s)? If you can, how much is that in some other quantity?

(Used to use FreeBSD 4, couldn’t support 12.5MB/s. Switched to Solaris.)

100Mb/s => 100-1000 visitors per second for a 125KB page, about 2000 req/s. About 500 million hits. About $8000/month.

Can you perform 2000req/s? Apache, Lighttpd, etc can do that.

How do you do 2000 req/s? 10 lighttpds => 200 prxy req/s. 1 lighttpd => 40 req/s x 5 Rails FCGI each. Cached everything except writing. Worked on a single CPU machine - 3.2GHz P4 with 4GB.

Also do shared hosting with a strange ruby “application” called strongspace. 8.6m emails recieved, 5.8m sent. 15m spams blocked, 300 emails/minute with bursts up to 60k mails/minute. About 400m page views.

Performs ~ 20 Mb/s constant, mostly SSH.

18 logical servers. Rails is the least-busy part on only 2 servers.

Buy slower CPUs and more RAM.

Uses T1000 ultrasparcs with Zones.

Not really about frequencies, about RAM.

[Hit cmd-W then enter, damnit. Lost stuff about power.]

CPUs 94% idle. Get more RAM.

Equilogic enclosures with iSCSI. Works well with ZFS.

Why DIY? because those other guys have crappy racks. [scary photo of The Planet’s Racks made out of metal kitchen shelves can be found on TextDrive’s Flickr photostream]

Keep it simple even if you’re starting big. Spend money to get a big rack, then grow into it.

= Joe Ob’Brien - Create your own tools - Building DSLs with Ruby

“Computer language that’s targeted to a particular kind of problem, rather than a general purpose language that’s aimed at any kind of software problem” – Martin Fowler

Examples: - rails - ant - rake - rSpec - Excel

Craftsman use jigs to help them out (Deirdre chuckles because she cuts dovetails by hand)

Ruby features that make them easy - method makers - blocks - method_missing - hooks - introspection - never too late to do anything - Code is data

Napkin Driven Development - Jim Weirich’s story about rake built on a napkin

customers :commercial do new_accounts do large.companies :compensate(3.usd) small.business.compensate(1.usd) end credit_cards do corporate.cords.individual.compensate(5.percent) corporate.cards.company.compensate(5.percent) end end

Ruby gives you enough flexibility that you can keep good coding practices.

Book coming out from pragprog about building DSLs with Ruby. Yay.

[Napkin sketch] target “compile” do java.compile JAVA.SRC end

** SDForum Ruby/Rails SIG ?

*** Alex Chaffee’s Agile Web 2.0 Talk

Web 2.0 * Thick Client all over again * Client: CSS, XHTML, Javascript [Its the DOM that sucks] * Protocol: HTTP, AJAX, JSON * Server: RoR

If you get a JSON object, you just have to eval it and suddenly it’s javascript.

For caching and performance, you want to keep as much stuff static “as makes sense.”

The Bad News * > 50% of time in JS

Server-Side * Ruby * Rails * ActiveRecord * Test::Unit * YML Fixtures

Ruby “I always knew one day Smalltalk would replace Java. I just didn’t know it would be called Ruby.” – Kent Beck (attr.)

Dynamic, Concise, Elegant, Powerful, everything is an object, DSLs are a piece of cake.

Ruby Cons “With great power comes great responsibility.” – Uncle Ben Parker

Also have to worry about people adding things to Object when it may not be appropriate.

(this all sounds a lot like Just Plain Whining to Deirdre)

“If you have people who don’t know what they’re doing, they still won’t know what they’re doing in Ruby.”

Ruby on Rails * This is not a talk about Rails - Rails is mostly excellent - “It’s the best webapp framework I didn’t design myself.” - Alex - Design by convention - Readable URLs ActiveRecord * Easy to get started * Transparent

ActiveRecord cons * Tuning takes work * Hurts test performance * Dynamic field introspection breaks encapsulation (yeah, but I don’t like having my schema in my class file)

SQLite can use in-memory DB, but doesn’t support transactions

[Discussion about dependency injection - why its hard with Rails]

[Rant about YAML, which isn’t a part of Ruby per se]

[Lots of rants are about the evils of Rails, not specifically Ruby-centered]

[2:30pm] He needs to be shoved in a factory factory [2:36pm] lol @ “Deirdre: He needs to be shoved in a factory factory”

[Stupid stand up and do some simon says]

[2:41pm] Simon says STFU

JavaScript: it’s more like a supervillain than a superhero.

JavaScript Cons: * “this” isn’t always corect - use bind * frustrating syntax and semantics - symbols are global by default - Null vs. Undefined vs. 0 - Object::Hash - All members public

prototype.js Library * bind * $ * $H, $A, each, etc. Rubylike JS stuffs. * Ajax.request

Firefox Extensions * Web Developer * Firebug * Venkman

JSUnit * Unit tests for JavaScript * Remote mode

CSS & XHTML * Better than tables and FONT tags - but just barely (says Alex, I disagree) * CSS has baffling gaps (in Alex’s knowledge?) - “I want to center this” margin-left: auto; margin-right: auto; works for modern browsers (and IE 6) - “Put this next to that” (funny, I haven’t had problems with that mostly) - Constants (e.g. color values) – guess he hasn’t heard about RCSS. http://rcss.rubyforge.org/ (rant about AJAX + RHTML) # hard to debug the protocol per se, Alex likes JSON better

Deirdre–you are a champ… I want to stab the guy.

I didn’t rant as much as I wanted to in that last talk. :)

= RedShift - Mixing Ruby and C for high-performance hybrid system simulation Joel VanderWerf California PATH, UC Berkeley

Nobody funds robot cars now, no 2’ between cars for ultra-high capacity.

The problem: Cars interact in a continuous world - Laws of physics - Ordinary Differential Equations - ODE - Functions of time but the functions are not always continuous

Discrete behavior - responds to variables crosing thresholds

Some continuos processes are easier described discretely - gear shift, brake activation, perception of red light

Go hybrid! - periods of continuity followed by jumps

Hybrid automata FSM with continuous variables and an ODE that governs continuous variables. guarded transitions to other states based on continuous variables. transitions can reset variables.

Still cannot fully predict - must use simulation, YMMV, floating point inaccuracy.

[Diagrams about HAs with transitions, thermostat example]

What are HAs used for? Automated high systems, multi-agent systems, teja.com, system verification, monte carlo simulation

Need smarter drivers!

Need networks of HAs so that events can propagate among drivers. Dataflow for variables.

Dynamic reconfiguration - lane changing/passing changes which car is in front.

No other tools that have networks of HA that reconfigure themselves.

Built SHFIT - Hybrid System Tools Interchange Format - Originally built for automated highways

For real projects it needs to be: - programmer friendly - modeler friendly - reasonably fast - free

Ruby fits all these except possibly ‘fast’

Need to use this fancy algorithm (Runge-Kutta 4th Order) to be reasonably accurate. It isn’t easy to do in Ruby without writing C. Can’t include some other library, too hard, license issues, needs to interact with ruby, would have to modify interpreter/core.

Instead, use code generation for stuffs.

[CShadow, C-like code generator in ruby]

CShadow, mostly for math C types

[thermostat example, clean code]

Can mix fast C with ruby cleanly.

Can attach observers

Limited to C expressions, may define C macros, functions, libraries

[Bunch of neato mathy RedShift examples]

Within a factor of 2 of MATLAB

Can be used in ODE and DES as well as HS

Mature, 5 years old and stable. Runs with GCC and MSVC.

Recompiles quickly, tries to be smart

IRB breakpoints during simulation

Persistence

Efficiency tips: - common subexpression optimization

What’s missing? - Native matrix variables - Other integrators besides Euler and RK4 - libtcc back-end during development - Documentation, examples, tutorails

Potential for fun