- Jim Freeze: Teaching Ruby in a Corporate Environment - EDA: Electronic Data Automation - Course history - 20 lessons to learn how to parse a file - student background: EE's who know enough to shoot themselves in the foot - homework: exercises and labs - labs took hours for what a seasoned Ruby programemer would take 5 minutes - Now condensed to a 2.5 day course - Course overview - Student profile - Tools: irb, ri, editor, cmdline - require index, quick help guide - Course outline - Curriculum - Have fun! (tough w/ engineers, ha ha) - in irb - 2*2, 2**2, 2**2**2**... - 5*4, 5.methods, 5.class, Fixnum.methods - Basics: naming, control flow - Variables, methods, classes, objects - People need to see something in their own context so they can understand it - Stackup class - Something to do w/ electronic devices? - Stackup class -> FET class - now it makes sense to the EE's - Regular expressions - some experts in the audience -- be careful not to leave the rest of the class in the dust - Blocks/procs/lambdas/iterators/whatever - one of Ruby's roughest areas and an area that has the roughest success in class - Tying up loose ends: forking, etc. - Corporate customizations: local repositories, best practices, etc. - Sending email, http data mining - Course flow/intensity - Avoid extremes: - intensity in classes - keep people awake w/ irb - 2-5 minute exercises before teaching - Technique would not work well for remote classes - Publicity - Website: rublog - Infrastructure - Test_All.rb, rake - rake files for tests would be really cool - Code repository - lightweight application review board - Code review - Keep ruby code looking like ruby - Keep things simple ("we're not perl coders on an ego trip") - Code reuse - local libs and 'global' libs - Best practices - Be patient, be a teacher - Facilitate integration, take no credit - Promote ruby coders, not ruby - What next? - Open sources courseware? - Rich Kilmer: Ultralog project - Can we build a system that operates with 45% loss of infrastructure? - Cougaar Multiagent System - 800K LOC java - component-based, robust, secure, open source - components run on agents which run on nodes which run on machines - Goals: automation - Automate configuration (kickstart machine) - Configure society (1M lines XML) - Build management - Manage society execution - Schedule execution, kill agents, etc. - All automated by ruby (for testing reliability of the system) - AUtomate reports - UltraLog dashboard - ACME in Ruby - Why Ruby? - Cross-platform and extensible and scalable - ACME Architecture - Scheduler runs ACME scripts - ACME service controls nodes - built with Freebase plugins - ACME scripting - Actions: do_action "" - Scripting example - Pure ruby, but looks domain-specific - Transformation rules - Empowered the end-user to write rules himself without going through the database or Java folks - Society persistence - Store in both ruby and xml - Why ni Ruby? - because Ruby's parser is fast - State examples - 2.hours + 5.minutes -- programmers loved this - Building Actions - dependencies between actions to ensure correct order of execution - society inherits from Cougaar::Action - Reporting - evolution: Event-based --> sequence-based --> code-driven --> data-driven (in YAML) - Message Router - Jabber is great for humans, but not designed for high-volume between machines - Future Directions - http://cougaar.org/projects/acme - RATIFY - Ruby Automated Test & Integration Framework.. Yeah! - Control infrastructure in distributed environment - Built-in DNS service discovery (Rendezvous) integration - Austin Ziegler: Ruwiki: Using & Extending - Going to be the default wiki on Rubyforge; may replace Usemod on Rubygarden too - Original by Alan Chen; colaboration between Austin and Alan since late 2003 - History - Why Ruwiki? - CGI or Webrick - Cleanly separated templates - Anti-spam - Two steps to installation: unpack, open in browser - Rubygen/RPA installation: - ruwiki install cgi --to - To move ruwiki elsewhere: - ruwiki_servlet -gem-data - Extending Ruwiki - APIs may be unstable - Can extend: tokens, backends, translations, templates, network handles, actions - Tokens: basic formatting object, regex-based - Translations - map symbol => string - Backends - could add SQL backend, but struct requirement on it - Templates - based on Dave's rdoc templates - tokens define CSS classes - Network Handlers - request and response objects are separate - use cookies to integrate with Rubyforge logins - Actions - Ruwiki currently monolithic, but in the future will use action objects (similar to the command pattern) - Default action: show - Future - Anti-spam, probably requiring pipeline changse - View diff revisions - Function tokens - makes it easier to add tokens, without specifying them using regexes - Vector search - Static content - headers/footers, e.g. - Recent changes for the entire wiki (will enable an RSS feed) - Full authentication, not just for Rubyforge logins - Page meta-data editing - Page can be set non-editable (to "freeze" discussions) - Questions - How easy will it be to roll back changes for a given IP? - ideally, one click - Not as simple a problem as it sounds - Why Ruwiki over instiki? - Doesn't require webrick - More extensible - Hal Fulton: Tycho: A Ruby-based PIM - PIM = information manager, not contact manager/rolodex - Goal: Manage all kinds of information from of varying sources and types - Related software - "Mind mapping" software (MindMapper / Visual Mind / The Brain) - "Traditional outlining software (vim, e.g.) - Treepad - Freemind - one of Hal's favorites - All Java - too heavily graphical; can't have many child nodes, else the display is messed up (so flat lists don't work) - InfoSelect (www.miclog.com) - Windows-only - Legacy software: Commence (IBM), Ecco - Inspiration for Tycho: InfoSelect (Tornado on DOS) - Paradigm: Piles of sticky notes - every keystroke eliminates notes that don't match - Why Tycho - open-source, cross-platform - eliminate code bloat / feature creep - have to be able to say "no" to users' requests for new features - expose a usable API - written & scriptable in Ruby - Screenshot - Basic concept - Topics organized in a hierarchy - Notes associated with each topic - Notes in a flat file; topics in a DBM - All data stored internally as YAML - Most recently used list - Metadata in each note - Some bugs remain - The Tycho API - full manipulation of topics and notes - TODO: better metadata - Ideas: - use to update websites via RSS feeds - hyperbolic interface (see StarTree at inxight.com) - inheritance model - applets - P2P data sharing - Rich Kilmer: Project Alph - Flash architecture - Flash player - a plugin - Flash IDE - for creating content - Flash vs. Flash Professional (more widgets) - Stack-based VM (runs bytecode) - Rich API for graphics - no file access - SWF file contains byte-code instructions - has graphics primitives - compiled from ActionScript (an ECMAScript variant) - only one (two?) compiler - Cross-platform plugin (uses original Netscape API, and activex) - Stateful client - Browser downloads swf file from server via http - Flash player can connect to server via socket API - e.g. Macromedia Flex - Flash 2004 - Actionscript 2.0 (based on ECMAScript 3.0) - Classes/Packages/Interfaces - Components 2.0 - binary distribution of components - ActionScript development - Code in vi/emacs/xcode - Compile in Flash - Each class a file (like Java) - No threads! - Alph architecture - Elements of Alpha: ruby, alph, swf frame, jar, swf/flash - Alph wire protocol - RMI protocol between ruby/flash, ruby/java - Methods: eval, new_object, call_method, call_method w/ callback, reply - Types: true, false, string, integer, ... - Alph in Ruby - FlashVM class lets you call into flash runtime - Alph code example - Demo - Button, minimize, alert ("Error: no/cancel"), list box, scroll pane - Ichat - uses rendezvous (automatic server discovery via multicast) - flash app to view Rendezvous data - Rich can never dmo just one thing at a time - Future plans - Popup menu support - Layout managers - Flex-like UI creation - Utopia bindings - Patrick May: Narf: a look at a 2 year-old framework - Hello world: - require 'web' - Web::process { puts 'Hello, world' } - CGI scripts are cmdline apps - Testing: checking HTML is ugly - Solution: Narflates - don't check the html - Checking/submitting forms in tests - Narf apps can run as cgi, fcgi, webrick - Main test site for Narf: open-ground.org - Templating - idea of "template include path" - lets different templates be used very easily - Web::Wiki - HTMLArea - rich-text area for browsers via dHTML (not part of Narf) - "It is inevitable that someone will abuse your site. Waste their time, not yours." - Wiki "tarpit" feature - known vandals think they have made changes, but haven't - Future directions - Integration with other libraries (RD, Rdoc) - Integration with WebUnit - More php parameter convenience - RSS feeds for Web::Wiki - Categorization/topic map for Web::Wiki - James Britt: ruby-doc.org - Website for Ruby documentation - Quick history - complaint on ruby-talk from a Python user that Rucy lacked sufficient documentation - James Britt, Jim Freeze, RubyConf.new(2002) - started plans - Dec. 2002 - ruby-doc.org launched - Version Zero - links to ML, pickaxe, known documentation - periodic news postings (blog) - content was hand-authored - Version Zero Point something - Ruby documentation bundle (Gavin Sinclair) - FAQ, pickaxe - getting old (most content for Ruby 1.6) - URL queries - retrieve ri/pickaxe content using simple URLs - Version Zero Point Something or Other - Documentation for the stdlib (Gavin Sinclair) - now added to the Ruby core itself - Site acquired more content over time - Euruko 2003 videos - Translations to french/german - Problems - ri lookup is broken - difficult to find things on the site - hard to add stuff (too much information repeated in multiple places) - Current goals - "Help James be lazy" - Facets and metadata - Most blog tools make you think too much (content gets forced into narrow slots) - better: automatic categorization (John Udell) - add smarter data; let the software figure out what to do with it - What this buys us - better searching/navigation than "big list o' docs" - Where this may lead - Actual location of document matters less - Services - Future goals - Make it easier to add content - Allow people to annotate content - ala Phrogz's version of online pickaxe (old pickaxe book plus annotations) - Comments on content - David Hansson: Ruby on Rails - Rails - "just enough to make the creation of database-backed web applications tolerable" - The Rails MVC - Active Record / Action View / Action Controller - Also Action Mailer (not part of the core) - Competing forces - PHP - easy to write web apps quickly (immediacy) - Java - community focused around cleanness, usability (ivory tower) - Opportunity of Inexperience - only possible to fix problems when you are still annoyed by them and not accustomed to them - Make the masses realize Ruby - package up annoyances with Ruby into a black box that makes the problems go away for newcomers - Design model / "Mantras" - DJ - remix old ideas - "Discount innovations" - Less software - say no by default; extract the essence of a good idea - Frameworks are retrospective; they are extracted, not built - Convenience over configuration - but give the appearance of choice - Passion is infectious - the art of picking figures - stay on the "winning path" - create more "happy people" - Be compassionate - Proud pieces - Recommended directory structure - Preconfigured logging - Lots of stubs (but not generative programming) - One-word template layouts - one layout file with header and footer that pulls in other templates - Ability to interact with environment/domain model with irb - people = Person.find_all(...) - p = people.select { |p| p.last_name == "..." } - p.password = "foobar123"; p.save - Features Almost here - Action mailer - easy to create service layer to send out email - Going OO on associations - relations in DB become OO (Florian Weber) - ERb template caching (Andreas Schwartz) - Rails 1.0+ - before end of 2004 - needmore database adaptors - Jim Weirich: The Many Facets of RubyGems - Quick tour - Flash demo - Query repositories (--local, --remote) - gem install - Enable Rubygems (Ruby -rubygems or export RUBYOPT=rubygems) - When in doubt, gem help [] - Other interesting gem commands: - gem update (upgrade all installed gems) - gem env (gem environmental info) - gem spec (print specification for a given gem) - Multiple versions - Version constraints - ==, >, <, >=, <= - ~> "approximately greater than" - Version constraints should ensure features have expected behavior (semantics) - A reommented versioning policy - compatible release - increment "build number" - Backward-compatible new features are added - increment minor version - Backward-incompatible - increment major number - Fictional project example - Some guidelines - Specific version knowledge is evil - Version resolution may fail (if e.g. two libraries have incompatible constraints) - Creating gems - 1. Create a gem spec - 2. Create the gem - gem build .gemspec - Using Rake - Rake::GemPackageTask - How Ruby finds libraries - using $LOAD_PATH - gems uses a different directory for each pck/version - require_gem searches installed gems for a gem that matches ther version constraints - Stubs vs. "require hack" - old versions of gems used stubs - hurts versioning aspect of gems - executables still use stubs - stubs can figure out what version to run via cmdline arguments - Genesis - the midnight hackers - Possible Rubygems directions - push toward 1.0, bug fixes - URI support - Better source/binaries support - Better tools for creating/using gems - rubygems.org Koichi Sasada: YARV: Yet another Ruby VM Who are you? - 1st degree PhD researcher, hyperthreading/SMP research - YARV - first step toward a parallel interpreter - Member of Nihon Ruby no Kai (Ruby community in Japan) - Favorite method: __send__ (a tradition of sorts for Ruby talks in Japan) - Ko1 - from Koichi - Japanese joke using the number 1 - Working on Kahua (scheme app server) part-time - Software: Rava, Ruscheme, Nadoka Why YARV? - Current Ruby interpreter too slow - AST traversed at run-time - myth: Ruby is a slow language - bytecode interpreter seems good - existing bytecode intrepreters: incomplete or slow - What is YARV? - VM for Ruby - funded by "Exploratory Software Development" - "Exploratory Youth" - by IPA - IT Promotion Agency, Japan - VM instruction set design, VM design, JIT, AOT - (AOT produces C source as output) - Goals - to be Rite - To be fastest Ruby VM (not hard) - To enable all Ruby features - easy to make "Ruby subset VM", but is it Ruby? - How to pronounse YARV? - doesn't matter; YARV will either become Rite or be forgotten - How to implement YARV? - simple stack machine - Ruby C extension - Wordcode, not bytecode - Use Ruby's existing infrastructure (GC, parser, Ruby API -- this makes memory management easy) - Compiler parses Ruby AST (compiler written in C) - 5 registers - Frames - Method Frame - identical to class frame - Control Frame - evrey frame has this - includes "self" - Continuation - Block Frame - Created when 'yield' is called - Proc - enables indefinite extent - moving environment to heap - creates block frame - environments connected via linked list - Exception/Jump - exception table, like Java VM - rescue/ensure clauses, retry point - rewind stack and check "this" table, if jump occurred - different from Java: must manage continuation SP register (Java VM only uses PC) - Ensure - if no jump, ensure is done by normal control flow - if exception raised, jump to ____(?) stack frame - What Instructions? - names not abbreviated - Instruction groups: - stack control - accessors - put something - apply change - method definition - method call/class/module_def (same group b/c class group is an expression) - control flow - optimization - How to write each instruction? - IDL - instruction description language - (body in C, declare variables, operands, values pushed popped) - parsed by Ruby - YARV optimization techniques - inline cache - "VM state version" counter - constant/method lookups use this - stack caching - 2 levels - super instructions (multiple instructions can be merged into one) - effective techniques because C compiler can do optimization - TODO: JIT compile - need an easy way - AOT compile - up to 100x improvement? - Is YARV working now? - Variables, class/module definition, method invocation - Current limitations - Can't call Ruby from C - Missing some Ruby features (such as set_trace_func) - How fast? - some benchmarks shown here - 1-2 orders of magnitude faster - Why not another VM? - vs Java VM, squeak, ... - nice library, optimizer - Tradeoff between optimizer and Ruby, stub - Is it fun? - vs Parrot - is register model really fast? - is it fun? - Schedule - Nov/Dec 2004 - AOT/JIT - 2005 - debug! - Mar - finish the fund - Future Work - Complete Ruby spec - optimizers - benchmark program - marshalling YARV instruction seq. - Nathaniel Talbot - "Test::Unit".downcase.sub(/::/, "/") - "test/unit" - _Learning_ a new language is "easy"; _thinking_ in a new language is hard - Ruby idioms: underscores, indentation, ||=, ...if...unless - Ruby vocabulary: unless, loop, scan, pp - Ruby grammar, semantics - nil and false are false; everything else is true - compose, don't inherit (ruby makes composition easy) - libraries are made up of files, not classes (classes can be extended) - Immigration and naturalization (coming to ruby) - What can we do to help newcomers? - Newcomers WILL bring pre/mis-conceptions - Best solution: cultural immersion (entice them then help them to see what is easiest) - Other culters have things to teach us, too - Our advantage: Ruby is imminently readable ("read the source" is a viable option) - Naturaliztion exam for Nathaniel: test/unit2 - Five simple pieces of testing: assertions, tests, fixtures, suites, runner (core, UIs) - Starting out with test/unit2 - Everything should be its own object, and those objects should be easier to manipulate - "magic" should make things easier, not just be "the way things work" - test fixtures replace setup/teardown - Slimming it down - simple AND easy - Use ruby's "declarative" style (instead of classes, use method calls and blocks) - Tests as documentation - example code extracted from tests; examples can be integrated with rdoc - What about test/unit? - backward-compatible changes backported to 1.8 - heavier changes released as add-on to 1.8 - Other things in store - Easier assertion writing - A re-runnable runner framework - Easier runner running - Test metadata - dependencies between tests (for acceptance testing; if this test fails, don't even try the others) - Live demo (of the prototype) - Closing Thoughts - Testing isn't hard; Java is hard - Shashank Date - Ruby webzine ('zine) - at artima.com - artima = leARn, ThInk, iMAgine - vision: educational project; everyone learns from everyone else - infrastructure in java/python - editor, advisory board - to be done: name, tagline, editor training, invitation for articles, article reviews, advertisements/sponsor - authors will be paid (if artima is paid) - no subscriptions - author owns copyright, but grants 30-day exclusive license to artima - editor's request - http://halostatue.ca/ruwiki/ruwiki.cgi/ - suggestions, please - look for announcement - submit good/original articles - translate - sponsor/advertise - Brad Cox: Objective C: A Retrospective - Brad Cox: An Object-oriented guy - 1980 - ITT, Object-oriented pre-compiler - PPI - Productivity Products International - Objective C + Foundation Classes - Venture Captital: PPI -> Stepstone - Book: OOP: An evolutionary approach - GUI library (cross-platform) - Automated Testing suite (like JUnit) - 1990 - Multitasking library (Taskmaster) - Book: Superdistribution: Objects as property - ... - Original goal: create technology that throws away noise and keeps signal ("groupware") - The 1980s - C and Unix and THAT's IT - No PC's, everything was PDP11 and VAX - Onyx, Fortune, Sun&HP - Mac just announced - No platform-independent GUIs (X was proprietary) - The Internet as we know it today was a decade away - Goal was coordination tools, not ObjC - Means was Robust Software, ObjC, C - Objects and messages - Smalltalk messages - someObject doThis: arg1 withThat: arg2 - ObjC messages - same as smalltalk msgs surrounded by square brackets - C-style function calls still present - Classes and inheritance - special syntax to create classes - +class_method - -instance_method - separate interface (.h) from implementation (.m) - @interface was not originally present - Messaging implementation - Messages compile to C calls to the _msg() function - Run-time: class hierarchy followed to find method implementation - Object points to structure that holds instance variables and dispatch table; this structure points to similar structure that holds class vars and dispatch table - sed script used to patch dispatch table with jmp instruction (originally) - alternate implementation - two implementations of _msg(), one which scans the dispatch table and calls the other - Software-ICs (using hardware as an analogy for software) - "class object" == "factory object" - object "super pointer points to ground - IC Packs (a marketing term...) - Foundation classes: object, arrays, collections - UI classes - like java AWT/swing - platform independent substrate that was hard to port/test - Multitasking (Taskmaster) _ threads/blocks/exceptions - based on longjmp/setjmp and asm - Questions - Why no GC? - hard to implement, as C is just a portable assembler - speed was an issue (reputation of GC at the time) - Why did C++ succeed and ObjC not? - C++ is no soldering gun; not a technical Q... - Why did NeXT accept ObjC? - C++ - yuck - Object Pascal - Steve Jobs was already out of Pascal - Brad Cox (Part 2) - The hardware industry's solution - Java not too different from asm 30 years ago - hardware industry - success depends on success of customer (interdependency) - chip makers earn an honest living by providing silicon components for others to use; no equivalent in software world - geometric growth for hardware industry - arithmetic growth for software industry - no traction in software industry (funny picture of card loaded so heavy it lifts the horse in the air) - Wooden pencil harder to build / more complex than "digital pencil" (simple word processor) - Supply chains - Wooden pencil - parts made of parts made of parts - world-wide network necessary to produce all the parts of the pencil - no economic models to produce equiv. in software industry; one person (or a small team) could have built the digital pencil - Software vs. hardware - hardware made of atoms (concept of "own") - sofware made of bits - immune to physical conservation laws - implications: copyright-based compensation cannot work long-term - advertising-based compensation - makes both TV and software horrible - use-right based compensation (ret a car vs. buying a car) - never seriously tried - related to licensing, but would be technologically enforced - goal: enforce economy by law of nature, not man - The Internet today - Text TV; nouse > signal, pop-up ads, spyware, privacy issues, spam (advertising) - owners and buyers at war (esp. in music industry) - Win-lose, not win-win - sellers treating buyers as thieves - buyers return the favor with P2P, etc. - Why not win-win? - Goal: put economic value on use of bits, not the bits themselves - Vaults - they focus on thieves, not customers - instead, should focus on buying/selling! - sales room: the opposite of a vault - focus on selling AND protecting via dynamic security (cameras, alarms, clerks, guards) - How would a usage-based system work? - revenue flows on use, not when bits are acquired - Applies recursively (user pays for app; app pays for components; end-user doesn't know the difference) - http://virtualschool.edu/maybank (see diagram on slides) - John Knight: Rubyx4DC - Point of presentation: to connect us with www.rubyx.org - Rubyx - a Linux distro or an OS? - Andrew's goal: to sell games (multi-user, distributed games); Rubyx provides an environment for this - Daniel Berger; Ruby on Windows - Windows Services - service == managed server program (daemon) - Windows has no fork/setsid/init - use services to run a daemon in the background - win32-service package - Example: viewing services - Controlling services: service_[start|stop|pause|resume|delete] - Use Daemon class to create new services - Example: "echo" service - Debugging services: Use the Event Logger - The Windows Event Log - Win32 equivalent of syslog - Use the event viewer to see events - win32-eventlog - Allows reading/writing - Reading EventLog - open/read/close - Can access event log on remote machine - Writing to event log - register an event source - crete message category file - use mc to generate header then dll - register dll with Windows - use report_event() to write an event to the log - Running commands - exec does not work - popen does work, but you can't use "-" character to open a new interpreter - win32-popen - works like Open3.popen3, but API is different - No fork() on win32 - win32-process library has rfork(), which restarts from beginning of program - Future plans - SAPI, IE Controller (Chris Morris has done this?), Screenshot, enhance existing modules - Jamis Buck: Dependency Injection in Ruby - Dependency Injection - Automates creation of objects and their dependencies --> lose coupling of components - a kind of "Inversion of Control" (other types of IOC: configuration control, concurrency, logging) - Example: Using Copland to automate logging of method calls - Example: Referencing other services - Service configuration - Packages define and contribute to configuration points - Services specify dependencies of configuration points - Unit testing - since creation of dependencies is abstracted, construction of mock objects is easy - Lifecycle management - service models: prototype, singleton (instance per thread), threaded - types of instantiation: immediate, deferred - Calculator example - converting an app to use Copland - 1. refactor all operations into their own classes - 2. manual dependency injection - 3. create package descriptor (package.yml) - service point = definition for a service - 4. specify dependencies in yaml file - 5. Copland::Registry.build - 6. registery.service('') - still want to make it easy for 3rd parties to add new functions - 7. create operations map (in package.yml) - 8. add parameters attribute to calculator (in package.yml) - Consistent logging - add log property to Calculator - now use @log.debug from the Calculator class - Interceptors - AOP-like functionality - A real example: packrat - http://copland.rubyforge.org/packrat - Other uses - A database abstraction layer (like DBI) - Object-relational mapping layer - Web application framework - "Framework glue" - Other features of Copland - service models - substitution symbols - customizable logging - listener/producer systems - Other packages for Copland - copland-lib, copland-remote, copland-webrick - Future directions - Type 1 IOC - Simplify API - Define dependeicnies in code - Rubyize (Copland is a port from Java) - Gordon James Miller: Code Generation in a Heterogenous Environment - Project: integration of hardware and software - First demo in python, used all resources on the machine (1G mem) - Difficulties - needs to run on a small portable platform (ruggedized Dulch laptop) - Software structure - lots of data converters, convert binary to various msg formats - converters are generated - Language decision: C++ - easy to port, fast, "small" executables - slow to develop, ugly - solution: code generation - use Ruby 1.8, ERB, ReXML - Ruby Guidelines for the project - standard distribution only (can't depend on being able to download dependencies in the field) - Data representation - XML - everyone already knows it - Validation done by the code generator - All documentation generated by XML - ERB (Embedded Ruby) Intro - Basic Strategy: XML --> data model --> ERB - Network messages - Each instrument hsa its own msg set - First N bytes specify type of msg - Network Object Model - if you feel you are doing something twice, perhaps it should be generated - Code Generation Example - Cmdline parsing also generated - Physical constants generated so they'll be the same across languages (MathML) - Benefits - single XML file to contain all information - separation of XML and code generator - easy maintenance (someone else can maintain this!) - Drawbacks - Ruby is still a niche language - ERB templates cryptic, hard to read - no one else can maintain this :( - Why not Corba? - Environment with 3s ping times and 90% packet loss; may need to burst over 90-second period before connection is lost -- no one has a system that can handle this well yet.