Thursday, February 26, 2009

data_fabric

DataFabric provides flexible database connection switching for ActiveRecord.

We needed two features to scale our mysql database: application-level sharding and master/slave replication. Sharding is the process of splitting a dataset across many independent databases. This often happens based on geographical region (e.g. craigslist) or category (e.g. ebay). Replication provides a near-real-time copy of a database which can be used for fault tolerance and to reduce load on the master node. Combined, you get a scalable database solution which does not require huge hardware to scale to huge volumes. Or: DPAYEIOB - don’t put all your eggs in one basket. :-)

Installation

  gem install data_fabric

How does it work?

You describe the topology for your database infrastructure in your model(s). Different models can use different topologies.

  class MyHugeVolumeOfDataModel < ActiveRecord::Base
data_fabric :replicated => true, :shard_by => :city
end

There are four supported modes of operation, depending on the options given to the data_fabric method. The plugin will look for connections in your config/database.yml with the following convention:

No connection topology: #{environment} - this is the default, as with ActiveRecord, e.g. "production"

  data_fabric :replicated => true

#{environment}_#{role} - no sharding, just replication, where role is "master" or "slave", e.g. "production_master"

  data_fabric :shard_by => :city

#{group}_#{shard}_#{environment} - sharding, no replication, e.g. "city_austin_production"

  data_fabric :replicated => true, :shard_by => :city

#{group}_#{shard}_#{environment}_#{role} - sharding with replication, e.g. "city_austin_production_master"

When marked as replicated, all write and transactional operations for the model go to the master, whereas read operations go to the slave.

Since sharding is an application-level concern, your application must set the shard to use based on the current request or environment. The current shard is set on a thread local variable. For example, you can set the shard in an ActionController around_filter based on the user as follows:

  class ApplicationController < ActionController::Base
around_filter :select_shard

private
def select_shard(&block)
DataFabric.activate_shard(:city => @current_user.city, &block)
end
end

Warnings

  • Sharded models should never be placed in the session store or you will get "Shard not set" errors when the session is persisted.
  • DataFabric does not support running with ActiveRecord’s allow_concurrency = true in AR 2.0 and 2.1. allow_concurrency is gone in AR 2.2.
http://github.com/fiveruns/data_fabric/tree/master

Master/Slave Databases with Ruby on Rails

Not terribly long ago, I announced Active Delegate, which was a really lightweight plugin that I developed to allow models to talk to multiple databases for specific methods. The plugin worked great for really simple situations, like individual models.. but when it came time to test with associations it fell apart. I haven’t had a chance to work on any updates and knew that it was going to take more work to get it going.

Earlier this week, we helped one of our bigger clients launch their new web site1. For the deployment, we needed to send all writes to a master database and a reads to slaves (initial deployment is talking to almost 10 slaves spread around the globe!). We needed something to get integrated quickly and decided to ditch Active Delegate for the time being and began looking at the following options.

I spoke with Rick Olson2 and he pointed me to a new plugin that he hasn’t really released yet. So, I’m going to do him a favor and announce it for him. Of course… I got his permission first… ;-)

Announcing Masochism!

Masochism3 is a new plugin for Ruby on Rails that allows you to delegate all writes to a master database and reads to a slave database. The configuration process is just a few lines in your environment file and the plugin takes care of the rest.

Installing Masochism

With piston, you can import Masochism with:


$ cd vendor/plugins
$ piston import http://ar-code.svn.engineyard.com/plugins/masochism/

You can also install it with the old-fashioned way:


$ ./script/plugin install -x http://ar-code.svn.engineyard.com/plugins/masochism/

Configuring Masochism

The first thing that you’ll need to do is add another database connection in config/database.yml for master_database. By default, Masochism expects you to have a production database, which will be the read-only/slave database. The master_database will be the connection details for your (you guessed it…) master database.

# config/database.yml
production:
database: masochism_slave_database
adapter: postgresql
host: slavedb1.hostname.tld
...

master_database:
database: masochism_master_database
adapter: postgresql
host: masterdb.hostname.tld
...

The idea here is that replication will be handled elsewhere and your application can reap the benefits of talking to the slave database for all of it’s read-only operations and let the master database(s) spend their time writing data.

The next step is to set this up in your environment file. In our scenario, this was config/environments/production.rb.

# Add this to config/environments/production.rb
config.after_initialize do
ActiveReload::ConnectionProxy.setup!
end

Voila, you should be good to go now. As I mentioned, we’ve only been using this for this past week and we’ve had to address a few problems that the initial version of the plugin didn’t address. One of our developers, Andy Delcambre, just posted an article to show how we had a problem with using ActiveRecord observers and masochism, which we’re sending over a patch for now.

As we continue to monitor how this solution works, we’ll report any findings on our blog. In the meantime, I’d be interested in knowing what you’re using to solve this problem. :-)

1 Contiki, a cool travel company we’re working with

2 Rick just moved to Portland… welcome to stump town!

3 The Masochism plugin README

http://www.robbyonrails.com/articles/2007/11/15/master-slave-databases-with-ruby-on-rails

QueryTrace

QueryTrace is a Rails plugin for pinpointing where in your Rails application that slow query is running. While ActiveRecord takes you half-way there by logging all queries and how long they’re taking, it won’t answer the question of where they’re being executed. Enter QueryTrace – once you have it installed, your logs won’t just tell you that you have a problem, they will pinpoint the exact location of that problem for you.

Installation

script/plugin install git://github.com/ntalbott/query_trace.git

Usage

All you have to do is have the plugin installed – QueryTrace takes care of the rest, including:

  • Only displaying when at the DEBUG log level
  • Honoring your log colorization settings

Example

Before

Schedule Load (0.023687)   SELECT * FROM schedules WHERE (schedules.id = 3) LIMIT 1
Resource Load (0.001076) SELECT * FROM resources WHERE (resources.id = 328) LIMIT 1
Schedule Load (0.011488) SELECT * FROM schedules WHERE (schedules.id = 3) LIMIT 1
Resource Load (0.022471) SELECT * FROM resources WHERE (resources.id = 328) LIMIT 1

After

Schedule Load (0.023687)   SELECT * FROM schedules WHERE (schedules.id = 3) LIMIT 1
app/models/available_work.rb:50:in `study_method'
app/helpers/plan_helper.rb:4:in `work_description'
app/views/plan/_resource_schedule.rhtml:27:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_resource_schedule.rhtml:24:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_schedule_listing.rhtml:5:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:3:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:1:in `_run_rhtml_plan__schedule_listing'
app/views/plan/index.rhtml:6:in `_run_rhtml_plan_index'
vendor/plugins/textmate_footnotes/lib/textmate_footnotes.rb:60:in `render'
Resource Load (0.001076) SELECT * FROM resources WHERE (resources.id = 328) LIMIT 1
app/models/available_work.rb:54:in `div_type'
app/helpers/plan_helper.rb:6:in `work_description'
app/views/plan/_resource_schedule.rhtml:27:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_resource_schedule.rhtml:24:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_schedule_listing.rhtml:5:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:3:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:1:in `_run_rhtml_plan__schedule_listing'
app/views/plan/index.rhtml:6:in `_run_rhtml_plan_index'
vendor/plugins/textmate_footnotes/lib/textmate_footnotes.rb:60:in `render'
Schedule Load (0.011488) SELECT * FROM schedules WHERE (schedules.id = 3) LIMIT 1
app/models/available_work.rb:50:in `study_method'
app/helpers/plan_helper.rb:4:in `work_description'
app/views/plan/_resource_schedule.rhtml:27:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_resource_schedule.rhtml:24:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_schedule_listing.rhtml:5:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:3:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:1:in `_run_rhtml_plan__schedule_listing'
app/views/plan/index.rhtml:6:in `_run_rhtml_plan_index'
vendor/plugins/textmate_footnotes/lib/textmate_footnotes.rb:60:in `render'
Resource Load (0.022471) SELECT * FROM resources WHERE (resources.id = 328) LIMIT 1
app/models/available_work.rb:54:in `div_type'
app/helpers/plan_helper.rb:6:in `work_description'
app/views/plan/_resource_schedule.rhtml:27:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_resource_schedule.rhtml:24:in `_run_rhtml_plan__resource_schedule'
app/views/plan/_schedule_listing.rhtml:5:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:3:in `_run_rhtml_plan__schedule_listing'
app/views/plan/_schedule_listing.rhtml:1:in `_run_rhtml_plan__schedule_listing'
app/views/plan/index.rhtml:6:in `_run_rhtml_plan_index'
vendor/plugins/textmate_footnotes/lib/textmate_footnotes.rb:60:in `render'

http://terralien.com/projects/querytrace/

Wednesday, February 25, 2009

jQuery 1.3.2 and beyond

jQuery 1.3.2 has been released and although it is mainly a bug fix maintenance release, it does a little more, including:

  • Elements Returned in Document Order
  • .live() Can Now Prevent Bubbling
  • :visible/:hidden Overhauled
  • .height()/.width() Overhauled
  • Selector Speed-up in IE
  • .appendTo()/etc. Now Return Inserted Elements

It is also fun to look at the grab back of possible features on the table for 1.4 and beyond. Here are just a few:

  • jQuery.require (require JavaScript modules and CSS to load before ready runs)
  • Dynamic loading of modules when they’re needed (would require synchronous script loading in core)
  • $.contains (determine if an element is inside another one)
  • Handle HTML injection in XML documents (serialize a DOM then insert)
  • Implement a .extract()/.detach() method (remove the element from the DOM, leaves events and data intact)
  • Use querySelectorAll for element-rooted queries
  • Piggy-back on a central data cache, if one exists.
  • Allowing a function as the “setter” argument for .css() — like we have in .attr() — and maybe for .val(), .html(), and .text() as well.
  • Offset: Faster Initialization, use parseFloat, boundingClientRect check
  • Events: Have img.load check for .complete in IE, Multiple binding with namespaces, Event scoping, .live() improvements
  • Ajax: Use JSON API if available to parse JSON, Dynamic loading of stylesheets
  • Effects: Synchronized animations, fadeTo show also show the element, if it’s hidden
http://ajaxian.com/archives/jquery-132-and-beyond

Tuesday, February 24, 2009

Mysql Replication Adapter

So you want to use multiple slave databases with Rails? How does this syntax strike you:

MyModel.find(:all, :use_slave => true)

A few months ago, there was quite a bit of noise in the Rails community about Rails’ inability to easily make use of multiple databases. Dr Nic quickly responded with a solution. Everyone rejoiced in the wonder of the community.

However, the solution lacks the syntactic sugar that Rails does so well. It also has the load balancing logic above the models in user code, rather than below them, where it seems to belong.

Enter Mysql Replication Adapter.

This library contains a Rails database adapter that helps your Rails app talk to a single write master and multiple read-only slaves in a very elegant way. The configuration is also more environment-oriented than connection-oriented, so it hides the concept of multiple connections from the programmer altogether. All you have to do is say that you want a #find, #find_by_sql, or aggregate function spread over slave databases and the adapter does it for you.

Similar to Dr Nic’s approach, you still have to explicitly say when you want your queries to be sent to a slave database. We opted for this approach over a silent automatic balancing option because it reduces your ability to accidently really bork something up by sending it to a database that is just slightly behind in replication.

Here at Rapleaf, we’re using this adapter in a lot of our projects, because it allows us to leverage the additional read bandwidth of our two slave databases.

Installation & Use
(This all assumes that you have Mysql master-slave replication set up in advance.)

First, install it via the gem:

gem install mysql_replication_adapter

Next, pop open environment.rb and add:

require 'mysql_replication_adapter'

to the top before the initialize loop.

(Note: It *has* to go before the initializer loop, or it will load too late.)

Next, open up database.yml and configure it like so:

development:
adapter: mysql_replication
database: yourdb
username: root
password:
host: localhost
port: 3306
slaves:
- host: slave1
port: 3306
username: readonlyuser
password:
- host: slave2
port: 3306
username: readonlyuser
password:

Finally, to actually have Rails use one of the slave databases for a given find, use syntax like this:

MyModel.find(:all, :use_slave => true)

That’s all there is to it. If you’ve specified slave databases, when you make the above call, a random slave will be chosen and the query executed against that database. If you try and do a write operation (like find_or_create_by_*), the adapter will throw an error, so don’t worry, you won’t be able to corrupt your database.

One nice feature is that if you’re logging queries, whether because you’re in development mode or otherwise, the log will tell you which slave database the query got sent to. This could be helpful for debugging purposes.

There are a few other ways to make use of slave databases, but I’ll leave that for another post. You can also check out the readme in the gem directory for more details if you’re interested.

http://blog.rapleaf.com/dev/?p=5

ffiruby-filemagic

Win32 Support? sorry.

A new implementation of the ancient ruby-filemagic gem (http://grub.ath.cx/filemagic/).
This version uses FFI to talk to the native library (JRuby friendly).
(Blurb from the original gem site follows)

What is FileMagic?

FileMagic is a Ruby binding to the magic(4) library, which you may know better as the file(1) command. The file command identifies the type of a file using, among other tests, a test for whether the file begins with a certain magic number.

Install:
Make sure you have the magic(4) library installed.

> sudo gem sources -a http://gems.github.com
> sudo gem install glongman-ffiruby-filemagic

After Install:

> sudo ffi_file_magic_setup
> irb
>> require 'ffi_file_magic'
=> true
>> fm = FFIFileMagic.new(FFIFileMagic::MAGIC_MIME)
=> #<FFIFileMagic:0x11a4d9c @cookie=#<Native Pointer address=0x13606f0>>
>> fm.file('rails.png') #supply a path to your own image
=> "image/png"
>>

http://github.com/glongman/ffiruby-filemagic/tree/master

FFI extension for Ruby

FFI is a ruby extension for programmatically loading dynamic libraries, binding functions within them, and calling those functions from Ruby code.

Sunday, February 22, 2009

23 Useful Ruby 1.9 Links and Resources

ruby-1-9-1.gifIt's approaching two weeks now since Ruby 1.9.1 was released, bringing with it not only a whole stack of extra performance and a new VM, but also a lot of compatibility issues. No pain, no gain!

Thankfully, the Ruby community in its typical way has got to blogging, writing scripts, and what not, resulting in a flurry of useful links and resources for those brave enough to test the Ruby 1.9.1 waters. So here come 23 useful Ruby 1.9.1 links and resources! If you have any others you wish to add, please leave a comment as people will be checking those out too.

Ruby 1.9.1 Specifically..

build_ruby19.sh - A quick shell / bash script that downloads Ruby 1.9.1 from ruby-lang.org then untars and installs it. It uses a "program suffix" of "19" so it shouldn't overwrite your existing Ruby 1.8 programs. Instead you'll end up with ruby19, gem19, irb19, and so forth. This strategy makes it a cakewalk to run two versions of Ruby at the same time. Want a script that installs both? Try this instead (it makes the 1.9 versions the "default" though). All somewhat based around these similar Web-based instructions by Ryan Grove.

Future proofing your Ruby code. Ruby 1.9.1 is coming. - Australian superhero Dr Nic Williams takes a look at using multiruby to run Ruby 1.9 and 1.8 on the same system. This is quite a different approach to just installing them separately with different suffixes and might suit your workflow better.. Ken Collins has also written MultiRuby The MacPorts Way which takes a slightly different approach.

Getting ready for Ruby 1.9.1 - The Phusion guys (behind the excellent Passenger / mod_rails) give some tips regarding running Rails apps on Ruby 1.9.1. They explain that you must move on up to Rails 2.3, that you'll need to patch a ton of gems, but that the latest build of Phusion Passenger will work happily with Ruby 1.9.1.

Ruby 1.9.1 - The Stuff It Gives Us - Justin Reagor presents an overview of 8 new features / differences (with code examples). For example, you can now overload operators like !, !=, and !~, hashes preserve their order, and newlines can go where no newline has gone before.

Is It Ruby 1.9 - A community site where you can track gem compatibility with Ruby 1.9 (Ruby 1.9.1 specifically, though) as well as make reports of your own. If you want to contribute to the community in any way right now, this is a good place to do it. Get those reports and fixes in!

Installing Ruby 1.9.1 & Rails from Source on Ubuntu Screencast - A 7 minute walkthrough of installing Ruby 1.9.1 and Rails from source on Ubuntu (rather than via apt-get) by Joon You. This should work on Debian as well.

Ruby 1.9.1 Release News - The official "NEWS" list from the 1.9.1 release. It doesn't go into details but presents a gigantic list that expresses what's new and what changed in Ruby 1.9.1 versus 1.8. Certainly worth a quick scan.

Ruby 1.9 Generally..

Migrating to Ruby 1.9 - Bruce Williams' presentation covering Ruby 1.9 at a high level. Lots of pithy code examples, M17N is covered, etc. A great resource if you get bored quickly as you can just flick through in a few minutes.

Working with Encodings in Ruby 1.9 - A very solid introduction to M17N (multilingualization) support in Ruby 1.9 with examples.

Changes in Ruby 1.9 - A classic guide to the changes in Ruby 1.9 by Mauricio Fernandez. Sadly it's not been updated since 2007 but it's such a gigantic list packed with excellent code examples that it should still be essential reading.

10 things to be aware of in moving to Ruby 1.9 - David A Black (of RubyCentral and Ruby for Rails fame) highlights 10 "gotchas" that could bite you in the ass when moving to Ruby 1.9. Includes String#each, block variables scope and semantics, the * operator, and more.

Fun with Ruby 1.9 Regular Expressions - Dave Thomas (of Pickaxe fame) presents a very compelling code example showing how regular expressions have grown up in Ruby 1.9. You can now write some pretty advanced parsers using the new features.

Getting Code Ready for Ruby 1.9 - James Edward Gray II wrote a year ago about some of the changes you'll need to take into account when moving from Ruby 1.8 to 1.9. Still good reading and the plentiful comments make it worth the trip.

Benchmarking Ruby - Evan DiBiase has just (as in, a few days ago) performed some benchmarks on JRuby 1.1.6 (and an early build of 1.2), MacRuby, Ruby 1.8.6, and Ruby 1.9.1. Benchmarks are always hard to get right, but he finds that while Ruby 1.9.1 is significantly faster than 1.8.6, JRuby is faster still. (I have found this to be true in my own work.. JRuby is on fire!)

The December 2008 Great Ruby Shootout - Antonio Cangiano's famous Ruby benchmarking shootout. It wasn't without flaws (what benchmarks are?) but it showed us that Ruby 1.9 is approximately double the speed of 1.8.

Pipelines Using Fibers in Ruby 1.9 - It's from all the way back in 2007 but Dave Thomas shows how to use Ruby 1.9's "fibers" feature to implement a pipeline of operations. Note that it leads on to a second part too.

Why you should use Ruby 1.9 with Prawn - Gregory Brown explains with Ruby 1.9 is so awesome for his Prawn PDF library. The tests run in half the time and Ruby 1.9's text encoding features make life a lot easier.

Arrow Lambdas, a Ruby 1.9 Vignette - A code-driven walkthrough of lambdas in Ruby 1.9 by Bruce Williams. This is the best casual walkthrough of the new lambda syntax(es) for 1.9 I've seen so far.

Ruby 1.9 can check your indentation - No, no, this isn't the start of a process leading to a Ruby/Python merger with Ruby 3.0 (though never say never).. it's just that Ruby 1.9 can now see if indentation is mismatched on things like if statements or method definitions and give you better warnings when you get things wrong. Another great post by Dave Thomas.

http://www.rubyinside.com/23-useful-ruby-19-links-and-resources-1498.html

JavaScriptMVC 1.5 Released

JavaScriptMVC is a framework that brings methods to the madness of JavaScript development. It guides you to successfully completed projects by promoting best practices, maintainability, and convention over configuration. Learn more...

New features include:

  • Env.js/Shrinksafe based compression: A custom env to simulate the browser. As the browser encounters script tags, it adds them to a collection and then compresses them. This means instant file concat and compression from the command line with no extra work.
  • Env.js Testing: Prior to 1.5, tests ran in the browser only. With Env, the same tests can be run from the command line. Great for projects where you need a quick way of checking if functionality works before check-in.
  • Documentation:New JavaScript based documentation library split between JSDoc and NaturalDocs.
  • Code Generators: Added code generators and made building custom ones easy too by using EJS.
  • Scaffolding: Helps you develop iteratively by connecting to default Rest services and providing an easily expandable CRUD interface.
  • Engines+Plugins: Added a command line plugin and dependency installer. So, if a developer wanted a jQuery plugin, he can install it from the command line, and it will also grab jQuery.
  • Custom Event Delegation: Besides improving event delegation to cover all the cases that even live doesn’t do, they’ve expanded it to include custom events such as drag+drop, lasso, hoverenter, mousenter. Developers can have the benefits of event delegation with these complex events.
  • Easy Update: JavaScriptMVC can update itself from the command line.
http://javascriptmvc.com/index.html

Cross-Browser Inline-Block

Ryan Doherty has one of those really nice articles that walk you through how to do something that should be easy in CSS but isn't, until you know how: Cross Browser Inline Block.

By the end of it all you will have this:

style:
    li {
width: 200px;
min-height: 250px;
border: 1px solid #000;
display: -moz-inline-stack;
display: inline-block;
vertical-align: top;
margin: 5px;
zoom: 1;
*display: inline;
_height: 250px;
}

li
div
h4 This is awesome
img "..."

which gets you the following reliably in many browsers:

Along the way you will learn about more IE star hacks, fun with hasLayout, use XUL stacks to help Firefox 2 along, and more. Very nice job Ryan.

http://ajaxian.com/archives/cross-browser-inline-block
http://blog.mozilla.com/webdev/2009/02/20/cross-browser-inline-block/

Thursday, February 19, 2009

JazzRecord is ActiveRecord for JavaScript (ORM)

ActiveRecord is a popular object-relational mapping layer for Ruby that provides an easy means for dealing with database tables, complex relationships between data models, and error validation. It’s a powerful, yet accessible library. JazzRecord is a free and open-source JavaScript ORM that seeks to minimize its learning curve by mimicking ActiveRecord style and conventions.

http://www.jazzrecord.org/

Visual Event

Events in Javascript are often seen as a bit of an enigma. This is odd given that Javascript is very much an event driven language, but it is typically down to their complex nature and difficulty to debug. To this end I've created Visual Event to help track events which are subscribed to DOM nodes.

When working with events in Javascript, it is often easy to loose track of what events are subscribed where. This is particularly true if you are using a large number of events, which is typical in a modern interface employing progressive enhancement. Javascript libraries also add another degree of complexity to listeners from a technical point of view, while from a developers point of view they of course can make life much easier! But when things go wrong it can be difficult to trace down why this might be.

It is due to this I've put together a Javascript bookmarklet called Visual Event which visually shows the elements on a page that have events subscribed to them, what those events are and the function that the event would run when triggered. This is primarily intended to assist debugging, but it can also be very interesting and informative to see the subscribed events on other pages.

http://www.sprymedia.co.uk/article/Visual+Event

Wednesday, February 18, 2009

Jemplate

JavaScript Templating is the best way to turn AJAX/JSON data into HTML. Jemplate is the best way to do JavaScript Templating.

Jemplate beats other JavaScript Templating frameworks hands down for the following reasons:

  • Jemplate is a complete port of the popular Template Toolkit framework. This means it is very full featured indeed.
  • Templates are precompiled (one time, on the server) as JavaScript functions. There is no JavaScript runtime penalty of compiling templates.
  • Templates are not stored in your HTML. No silly tricks, like putting template code in hidden textareas.
  • A browser downloads your templates once and caches them. Just like any other JavaScript code.
http://jemplate.net/

Monday, February 16, 2009

Jet Profiler for MySQL

Screenshot showing top used tables

Is real-time query performance and diagnostics tool for the MySQL database server. Core features:

  • Query, table and user performance
  • Graphical visualisation
  • Low overhead
  • Easy to use

Query, table and user performance

Jet Profiler focuses on queries, tables and users. This gives you the information you need most in order to quickly fix performance problems in your code, such as most frequent queries, most used tables or busiest users.

Graphical visualisation

Data is collected, analyzed and displayed in real-time in diagrams, pie charts and tables. You can easily drill down and navigate through the data.

Low overhead

Most of the profiling work is done in the Jet Profiler application, not in the database server. Therefore, the performance hit is normally negligible, around 1%.

Easy to use

It supports all MySQL versions. No database server changes are necessary. No agents or separate services are needed. Jet Profiler is a desktop application which runs on your computer. You start it, connect to a server, hit the record button, and see results within minutes. And it runs on Windows, Mac and Linux.

http://www.jetprofiler.com

Sunday, February 15, 2009

When can I use...

Compatibility tables for features in HTML5, CSS3, SVG and other upcoming web technologies

Related pages: HTML 5 Implementation list, CSS engine comparison, HTML 5 engine comparison

Detailed tables: Quirksmode, Web Devout

Notes:

  • Several features have not yet been fully defined, and thus have only experimental support.
  • Opera 10.* information is based on support in Opera 10a and the "Video build"
  • Internet Explorer 8 information is based on support in IE8 RC1
http://a.deveria.com/caniuse/#agents=All&cats=All&eras=All&statuses=All

Friday, February 13, 2009

IE NetRenderer

IE NetRenderer allows you to check how a website is rendered by Internet Explorer 7, 6 or 5.5, as seen from a high speed datacenter located in Germany. Just type in a URL in the field above and try it out - it's free!

New: We have updated the IE8 Beta 2 engine to Internet Explorer 8 RC1.

Unlike other screenshot services, we are able to process a large number of capturing jobs in parallel and in realtime, making it the fastest service that we know of.

This web rendering tool is ideally suited for web designers working on Apple iMac and Linux workstations. It allows to verify web designs natively on all popular Internet Explorer versions, without the need to set aside several physical or virtual Microsoft Windows PCs just for that purpose.

http://ipinfo.info/netrenderer

Thursday, February 12, 2009

begin + else

begin/end blocks accept (in addition to rescue and ensure) an else clause:

begin
# main code here
rescue SomeException
# ...
rescue AnotherException
# ..
else
# stuff you want to happen AFTER the main code,
# but BEFORE the ensure block, but only if there
# were no exceptions raised. Note, too, that
# exceptions raised here won't be rescued by the
# rescue clauses above.
ensure
# stuff that should happen dead last, and
# regardless of whether any exceptions were
# raised or not.
end

If you don’t have an ensure clause, else is pretty much the same as just putting code immediately after the end, but if the order matters (something should happen before ensure, and
only if the main code succeeded, and should not be subject to being rescued if something goes wrong), then else is your man.

http://weblog.jamisbuck.org/2007/2/8/begin-else

ruby script/console --sandbox

Loading development environment in sandbox (Rails 2.2.2)
Any modifications you make will be rolled back on exit

Monday, February 9, 2009

JS Charts

JS Charts is a free JavaScript based chart generator that requires little or no coding. With JS Charts drawing charts is a simple and easy task, since you only have to use client-side scripting (i.e. performed by your web browser). No additional plugins or server modules are required. Just include our scripts, prepare your chart data in XML or JavaScript Array and your chart is ready!

JS Charts lets you create charts in different templates like bar charts, pie charts or simple line graphs.



http://www.jscharts.com/

Friday, February 6, 2009

Recreating the button

Until some future version of HTML gives us new native controls to use in a browser, at Google, we’ve been playing and experimenting with controls we call “custom buttons” in our apps (among other custom controls). These buttons just launched in Gmail yesterday, and they’ve been in Google Reader for two months now. The buttons are designed to look very similar to basic HTML input buttons. But they can handle multiple interactions with one basic design. The buttons we’re using are imageless, and they’re created entirely using HTML and CSS, plus some JavaScript to manage the behavior. They’re also easily skinnable with a few lines of CSS, which was a key factor now that Gmail has themes.

Gmail buttons

I thought it would be interesting to provide a portion of the background on our buttons here, and discuss some of the iterations we’ve been through so far to get to the current state.

Background

Today’s web apps allow increasingly complex interactions. Users can view, create, manage, and manipulate all kinds of data, from email messages to feeds to photos to blog posts, or even choosing what their DVR records on any given night. We’re at the point where these apps need something beyond standard HTML form controls and basic hypertext links to represent the actions a user can take.

A basic could be used for single actions, a could be used for selecting mutually exclusive options. But we’re left with no way to represent other interactions common in desktop apps. Such as a checkbox that represents more than just on or off. Or the use of auto-complete to refine or narrow the options in a drop-down menu. On top of this, the controls we can render have significantly different appearances across browsers and platforms. Even within a single browser, buttons and select menus have quite different designs.

Enter: the concept of custom buttons.

The first iteration

Not long after I started at Google, I remember seeing mockups for a new product that eventually become Google Spreadsheets. The mockups I saw used simple buttons that looked similar to default HTML buttons in certain browsers. But they were subtly different than any default buttons I had ever seen before. The giveaway was seeing three buttons sandwiched together to make a pill button:

Spreadsheet buttons

At first, I thought they were just generic browser-agnostic representations — and wishful thinking for the appearance — of actual HTML buttons. But once we started using an internal-only version of the product, I realized this button design actually got built into the product. That was fine. But I cringed when I realized how the buttons had been implemented. Each button was set up with a nine-cell table so they could place each corner image, and still allow the button to expand in all four directions according to the width and height of the text inside:

nine-cell table

Eliminating the table and corner images

button 2.0 I knew there had to be a better way to render these buttons than using tables, and especially nine-cell tables just for the tiny little corners. So I tried creating a few prototypes to improve our button code. My first button attempt, which I named Custom Buttons 2.0, (version 1.0 would be the nine-cell tabled version done by one of our engineers) used a similar trick that I used for event chips in Google Calendar: the top border was one element with 1px left and right margins, the middle of the button was another element with left and right borders, and the bottom border recycled the styles of the top border with 1px left and right margins. This created a one-pixel notch in each of the four corners, giving the subtle illusion of a small rounded corner.

That 2.0 attempt was fine, and worked pretty well (as I expected) in almost all browsers. But it required that each button as a whole either be floated or positioned absolutely with a width. I wanted a set of buttons that could be treated as inline elements, and that would take up as much horizontal space as the text inside each button needed.

Going inline

My 3.0 attempt relied on treating the buttons and everything inside them as inline elements. The top/bottom borders still needed to be rendered separately from the left/right borders to get 1px-notched corners. The left/right borders were rendered on the outer element. The top/bottom borders were rendered on the inner element. Because borders don’t compound and add to the width or height of an inline element, we get the 1px notches in each corner. I ran into a lot of frustration with this inline approach until I remembered display: inline-block. That seemed to solve everything at once.

Demo page for Custom Buttons 3.0 A demo page for Custom Buttons 3.0 shows my progress to this point. As you can see there, I built in affordances for changing the border color on hover, and for reversing the gradient direction for the active/click state to make it feel like the button is actually pressable. I also attempted to show how we could sandwich multiple buttons together to form a pill button. The pill button wasn’t perfect — I didn’t want gaps in the top/bottom borders between each button. But it was a start.

The magical inline-block solved everything, except in IE. That’s where the genius of Google engineers came in. They knew how to get tricks working in all browsers, and this technique interested a couple of them enough that they dedicated the time to make it work.

So 3.0 buttons were fine. After some modifications by our engineers, they made it into live production code. I believe 3.0 buttons are currently still in use for edit buttons in Google Sites, and in editor modes for Google Docs. (As of this writing. Expect those to change in the near future to buttons described below.) But I was still bothered by the requirement of a background gradient image. Not only was this an extra request to the server, but if anyone wanted to change the colors of a button, they’d be required to create a new gradient image. This wasn’t flexible enough, in my opinion, and I thought we could push further.

Eliminating the gradient image

Instead of rendering the gradient with an image, I thought we might be able to simulate a gradient with a few bands of color. With a few light grays laid beside each other that were close enough in value, we’d get something that looked like a gradient. With only two bands of color, I got a glossy-looking button with a sharp division between the two bands of color. Not what I wanted. Adding a third band of color between the first two colors blended each color together better. So three color bands it had to be.

To get that band of color and fake the gradient, I had to insert one more element in the button code. I chose because it was short, and semantically, it didn’t mean anything. That element was absolutely positioned, so it could live inside the button and behind the text without affecting anything else. For the button itself, I used the almost-white #f9f9f9. For the element I used #e3e3e3. The element was absolutely positioned to the bottom of the button, and given a height of 40%. To get the middle band of color, I added a top border of #eee to the element.

Another demo page for Custom Buttons 3.1 shows my attempt at getting this pseudo-gradient to work. It works in Firefox and Safari, and probably a few other modern browsers. But not everywhere. It was never perfect, and I don’t recommend using it in production code. Again, I couldn’t get this working right in IE. Google eng to the rescue again. To see the final code we ended up using in Gmail and Reader, you’ll have to reverse engineer the button code in one of those products.

Sweating the details

If we were going to undertake the task of recreating basic HTML form controls, we knew there were a lot of details that need to be accounted for and thought through. Like all the possible states of a button: resting, hover, focus, active, toggled-on, and disabled. There are also the accessibility ramifications of creating non-standard controls. I’m sure we haven’t factored in or solved every access issue yet. But engineers are working on that. Here’s a glimpse of the many states and types of buttons, along with the visual specs we had to think about and create if we were really going to replace default buttons and menus:

Visual spec for Custom Buttons 3.1

Major credit

I certainly didn’t create the concept of custom buttons at Google. Nor did I write the final code that made it into production. I merely initiated a couple steps to improve the methods we use to render custom buttons. My portion of the iteration is what’s documented here. There were many other steps in making these buttons a reality.

These buttons never would have made it into production code without the help of several Google engineers. One of the primary aids, Emil Eklund, helped fix a lot of my code for these custom buttons, and got it working in the browsers Gmail supports. He just posted an entry on the Official Gmail Blog yesterday about the label and folder-like functionality behind the new buttons in Gmail. Two developers (no longer at Google) also contributed heavily to the original button code: Ryan Carver and Greg Veen. They deserve huge props too.

Even more credit for the launch of these buttons in Gmail goes to one of the Gmail designers, Michael Leggett, who dreamed up all the fancy new functionality and interactions behind applying labels. Michael gave me lots of feedback and suggestions as we were building the original specs for 3.0 and 3.1 buttons. He also created countless iterations of the button interactions for Gmail, and endured numerous reviews and feedback cycles to finally get them launched in the product. If you like the new labeling menus in Gmail, Michael is the one to thank. The menus are especially slick if you use the new v and l keyboard shortcuts, along with auto-complete to apply labels (and even archive at the same time) without ever touching your mouse.

There are numerous other designers, developers, and engineers at Google who touched these buttons at one point or another. They all deserve credit too. I’ve only given props to four of the most prolific people who made these buttons a reality.

These buttons don’t permeate the entire Gmail or Reader interfaces yet for all browsers. (e.g. Compose view is still using default buttons for older WebKit browsers.) But now that these buttons are reusable components, expect to see us using them in more places throughout Google as we find good uses for them.

http://stopdesign.com/archive/2009/02/04/recreating-the-button.html

GoF patterns in Ruby

Implementing almost all of the GoF patterns in Ruby:
svn checkout http://rubygof.googlecode.com/svn/trunk/rubygof


Docs: http://www.scribd.com/doc/396559/gof-patterns-in-ruby
Project: http://code.google.com/p/rubygof/

NOBODY KNOWS SHOES

Shoes is a cross-platform mini-gooey toolkit for the Ruby programming language written _Why. I installed Shoes on an Ubuntu box ran with it (bad pun intended).

Let’s move from puns to code. A simple Shoes application is wrapped around the following piece of code.

  1. Shoes.app :height => 250, :width => 200 do
  2. end

As you can see, a Shoes application is simply a Ruby block. You can pass in a hash or arguments with the values for the window’s default height and width. If you save the above piece of code as Appy.rb you can run it from the Shoes installation directory by running the following command.

./shoes Appy.rb

If you run the above application it simply opens a empty application window. An empty window is pretty much useless. An GUI application needs buttons and text fields to be of practical use. Lets add two buttons to our application that when pressed print out an informational bit of text to the console.

  1. Shoes.app :height => 200, :width => 200 do
  2. button "Button One" do
  3. puts "Button One Pressed"
  4. end
  5. button "Button Two" do
  6. puts "Button Two Pressed"
  7. end
  8. end

When working with soft gooeys the second thing one needs to learn after how to add a button is how to layout it out. As of this writing (Release 117), Shoes provides two layout managers, Stack and Flow. Stack lays out your components from top to bottom. The Flow layout container lays out UI widgets from left to right. Building on top of our Shoes application the following code layouts out the two buttons using the Stack cointainer with a 10 pixel margin.

  1. Shoes.app :height => 200, :width => 200 do
  2. stack :margin => 10 do
  3. button "Button One" do
  4. puts "Button One Pressed"
  5. end
  6. button "Button Two" do
  7. puts "Button Two Pressed"
  8. end
  9. end
  10. end

To add a simple text field just call the text field with the default text value.

  1. Shoes.app :height => 200, :width => 200 do
  2. stack :margin => 10 do
  3. button "Button One" do
  4. puts "Button One Pressed"
  5. end
  6. button "Button Two" do
  7. puts "Button Two Pressed"
  8. end
  9. text "Text Field"
  10. end
  11. end

Here is how the above code renders.

Running With Shoes

I would be a bit more practical if we can update the text field based on some condition, say when a button is pressed. Since we need to reference the text field in the code block for each button we need to have a variable for it. Also, instead of printing text to the console, we will display it in the text field.

  1. my_text_field = nil
  2. Shoes.app :height => 200, :width => 200 do
  3. stack :margin => 10 do
  4. button "Button One" do
  5. my_text_field.replace "Button One Pressed"
  6. end
  7. button "Button Two" do
  8. my_text_field.replace "Button Two Pressed"
  9. end
  10. my_text_field = text "Text Field"
  11. end
  12. end

As you can see, you can get started writing Shoes GUI applications fairly quickly. But as mentioned earlier, Shoes is a mini-GUI toolkit that is still under development. _Why has mentioned that he intends to keep Shoes small. From what I can gather from sample applications and the online code repository Shoes provides additional widgets such as an edit_line, edit_box, and list_box. But I was not able to find any information regarding tabs, check boxes, radio boxes, or trees.

In the next installment of Running with Shoes, I’ll go over it’s 2D and animation capabilities.

http://www.juixe.com/techknow/index.php/2007/08/27/running-with-shoes-a-mini-gui/
http://sergiosantos.info/2007/8/shoes-a-ruby-gui-toolkit
Download "Nobody knows Shoes"

JetBrains RubyMine

The Most Intelligent Ruby IDE

JetBrains RubyMine — new Ruby and Rails IDE built on years proven IntelliJ platform. RubyMine brings the whole range of essential developers tools, all tightly integrated together for creating the convenient development environment for productive Ruby development and Web development with Ruby on Rails.

Key Features

  • Intelligent Editor: code completion, code snippets and automatic refactorings
  • Project Navigation: wide range of views and one-click jumping between components
  • Error-Free Coding: on-the-fly code analysis and type inference
  • Web Development with Ruby on Rails (including
    best-of-breed HTML, CSS and JavaScript editing support)
  • RSpec and Test::Unit support, with GUI-based test runner
  • Ruby Debugger: full support for Rails applications debugging and easy-to-use interface
  • VCS Integrations: Git, Perforce, Subversion and CVS with changelists and merge
  • Open API and Plugin Development SDK, ensuring IDE extensibility and flexibility
Supported Languages
Technologies & Frameworks
Advanced Code Editing
  • Code Completion
  • Intelligent Coding Assistance
  • Refactoring
  • On-the-fly Code Analysis
  • Navigation & Search
  • Code Documentation
  • Code Generation
  • Code Style
Integrated Environment
  • Version Control Integrations
  • Local History & Diff Tool
  • Running/ Debugging
  • Rake Support
Customization & Extensibility
  • Project Configuration
  • IDE Customization
http://www.jetbrains.com/ruby/index.html

Wednesday, February 4, 2009

RailsApp Monitoring

  • Rails monitoring without the enterprise cruft.
    Tired of setting up complicated monitoring systems on each of our servers we asked: why not manage it all from a single web interface? Scout was born. Originally an internal tool, we discovered a community of Rails developers that wanted to make monitoring easier. Scout now lets any developer make smart decisions about their Ruby on Rails applications and servers.
    http://scoutapp.com
  • FiveRuns
    TuneUp - Free and Easy - Optimize your Rails andMerb application performanceCatch potentially costly performance and scalabilityproblems before your applications go into production with FiveRuns TuneUp.
    Manage - Monitor Rails application performance in productionEnsure your production Rails applications are performing at their best. FiveRuns Manage is the only application that gives you visibility into every part of the Rails stack — from OS to app.
    http://www.fiveruns.com/
  • BleakHouse: Tool to find memory leaks in your Rails applications

    Bleakhouse

    Bleakhouse is a new Rails plugin by Evan Weaver that helps you find memory leaks in your Rails applications. It does this by hammering ObjectSpace for information throughout the execution of your app and by producing pretty charts to show you what's going on. It's easy to install and get running, so if memory leaks or application stability have proven to be sore points for you, give it a try straight away.
    http://blog.evanweaver.com/files/doc/fauna/bleak_house/files/README.html
    http://blog.evanweaver.com/articles/2007/04/28/bleak_house/

Joose - A Meta Object System for JavaScript

Joose 2.0 "death of parseInt" released

The Joose team is very proud to announce the release of Joose 2.0.

Joose is a self-hosting meta object system for JavaScript with support for classes, inheritance, mixins, traits, method modifiers and more.

Joose makes object-oriented programming with JavaScript easy, declarative and very productive. The Joose meta-object system is multi-paradigm. It supports class-based and prototype-based programming styles as well as class-based inheritance and role-based extention.

The Joose framework has been successfully used in multiple production systems for twelve months now and has been proven to be very stable. Joose is being tested using an automated unit-test suite that is being run in all major browsers (Firefox, IE, Safari, Opera and Chrome).

To get started with Joose we recommend to read the getting started guide.

http://joose-js.blogspot.com/2009/02/joose-20-death-of-parseint-released.html

Designing Web Interfaces with Bill Scott and Theresa Neil

Bill Scott presented Designing Web Interfaces, a slideshow based on core items from his book (co-authored by Theresa Neil).

There are some really interesting posts on the site, such as 30 Essential Controls. Theresa has been pinging the major frameworks and will be posting a matrix of coverage by the various frameworks. But more generally it is a nice checklist of controls that can liven up an interface.

http://ajaxian.com/archives/designing-web-interfaces

Sunday, February 1, 2009

Migrating to Ruby 1.9

Bruce Williams
Rubyist since 2001

Perpetrator of much random Ruby hackery, language tourist

(Full-time since 2005)

Open source developer, contributer, technical editor, designer Occasionally blogs at http://codefluency.com

Ruby 1.8
Stable. The syntax and language features you know and probably love. The performance profile you know and might hate a little.

Ruby 1.9
Unstable, transitional. Many new syntax and language features. Better performance, especially for computationally intensive operations.

1.9 is a hint.

1.9 is a hint.
Get ready for 2.0.

Standard Library + ~ rubygems (+ prelude & ruby --disable-gems), rake, json (pure, ext), ripper, probeprofiler, securerandom, HMAC digests csv replaced by FasterCSV implementation soap, wsdl, base64, some rarely used, old libraries

Parser Changes

Flexibility and Obscurity (for the moment)

Parser Changes
  • New Hash Literal
    {a: "foo"} # => {:a=>"foo"} {a: "bar", :b => "baz"} # => {:a=>"bar", :b=>"baz"}
  • New Proc Literal
    multiply_by_2 = ->(x) { x * 2 } # => # multiply_by_2.(4) # => 8
  • Splat more flexibly
    names = %w(joe john bill) [*names, 'jack'] # => ["joe", "john", "bill", "jack"]
  • Method parameter ordering
    def say(language=:english, text) puts Translator[language].translate(text) end say "hello" # hello say :spanish, "hello" # hola
Migration Risk Factors
Text processing “Clever” assignment with blocks Some Hash enumerations Metaprogramming, code generation

Tests are Good
I was surprised at how much work my 11th hour integration of the FasterCSV code was. It was a pure Ruby library that really didn't do a lot of fancy tricks, but I had to track down about 20 little issues to get it running under Ruby 1.9. Thank goodness it had terrific test coverage to lead me to the problem areas.

- James Edward Gray II
Follow-up at http://blog.grayproductions.net/articles/getting_code_ready_for_ruby_19

Block Local Variables
Arguments are always local

Ruby 1.8
item = 1 2.upto(4) do |item| p item end # Outputs: # 2 # 3 # 4 item # => 4
Ruby 1.9
item = 1 2.upto(4) do |item| p item end # Outputs: # 2 # 3 # 4 item # => 1

Shadowing Variables
You’ll get a warning

Ruby 1.8
i=1 lambda { |i| p i }.call(3) # Outputs #3 i # => 3
Ruby 1.9
i=1 lambda { |i| p i }.call(3) # Outputs #3 i # => 1
-e:2: warning: shadowing outer local variable - i

Shadowing Variables
Locals, but warned
No local, reassigns
d=2 -> { d = 1 }.() d # => 1

Local, shadowed
d=2 ->(;d) { d = 1 }.() d # => 2
-e:2: warning: shadowing outer local variable - d

(Ruby 1.9)
Hash#select (etc)
Ruby 1.8
conferences.select do |data| p data end # [:euruko, "Prague"] # [:scotland_on_rails, "Edinburgh"] # [:railsconf_europe, "Berlin"]

Changes to yielded arguments

Ruby 1.9
conferences.select do |data| p data end # :euruko # :scotland_on_rails # :railsconf_europe conferences.select do |name, city| p [name, city] end # [:euruko, "Prague"] # [:scotland_on_rails, "Edinburgh"] # [:railsconf_europe, "Berlin"]
warning: multiple values for a block parameter (2 for 1)

Hash#select (etc)
Returns a Hash

Ruby 1.8
conferences.select do |name, _| name == :scotland_on_rails end # => [[:scotland_on_rails, "Edinburgh"]]
Ruby 1.9
conferences.select do |name, _| name == :scotland_on_rails end # => {:scotland_on_rails=>"Edinburgh"}

Features
Lots of changes, some big ones

Multilingualization
(m17n)
There is one type of string, and the encoding is mutable Strings are no longer Enumerable (use #each_char, #each_line, etc) The encoding is ‘lazy’ and can be set by probing with String#ascii_only? and String#valid_encoding?. Various ways to set default encoding (commandline, magic comments)
String#[] now returns a String, not a Fixnum (use ord)

[:ASCII_8BIT, :Big5, :BIG5, :CP949, :EUC_JP, :EUC_KR, :EUC_TW, :GB18030, :GBK, :ISO_885 9_1, :ISO_8859_2, :ISO_8859_3, :ISO_8859_4, :ISO_8859_5, :ISO_8859_6, :ISO_8859_7, :IS O_8859_8, :ISO_8859_9, :ISO_8859_10, :ISO_8859_11, :ISO_8859_13, :ISO_8859_14, :ISO _8859_15, :ISO_8859_16, :KOI8_R, :KOI8_U, :Shift_JIS, :SHIFT_JIS, :US_ASCII, :UTF_8, :UTF _16BE, :UTF_16LE, :UTF_32BE, :UTF_32LE, :Windows_1251, :WINDOWS_1251, :BINARY, :I BM437, :CP437, :IBM737, :CP737, :IBM775, :CP775, :CP850, :IBM850, :IBM852, :CP852, :IBM85 5, :CP855, :IBM857, :CP857, :IBM860, :CP860, :IBM861, :CP861, :IBM862, :CP862, :IBM863, :CP 863, :IBM864, :CP864, :IBM865, :CP865, :IBM866, :CP866, :IBM869, :CP869, :Windows_1258, : WINDOWS_1258, :CP1258, :GB1988, :MacCentEuro, :MACCENTEURO, :MacCroatian, :MA CCROATIAN, :MacCyrillic, :MACCYRILLIC, :MacGreek, :MACGREEK, :MacIceland, :MACICE LAND, :MacRoman, :MACROMAN, :MacRomania, :MACROMANIA, :MacThai, :MACTHAI, :M acTurkish, :MACTURKISH, :MacUkraine, :MACUKRAINE, :CP950, :EucJP, :EUCJP, :EucJP_ms, :E UCJP_MS, :EUC_JP_MS, :CP51932, :EucKR, :EUCKR, :EucTW, :EUCTW, :EUC_CN, :EucCN, : EUCCN, :GB12345, :CP936, :ISO_2022_JP, :ISO2022_JP, :ISO_2022_JP_2, :ISO2022_JP2, :ISO 8859_1, :Windows_1252, :WINDOWS_1252, :CP1252, :ISO8859_2, :Windows_1250, :WIN DOWS_1250, :CP1250, :ISO8859_3, :ISO8859_4, :ISO8859_5, :ISO8859_6, :Windows_1256, :WINDOWS_1256, :CP1256, :ISO8859_7, :Windows_1253, :WINDOWS_1253, :CP1253, :IS O8859_8, :Windows_1255, :WINDOWS_1255, :CP1255, :ISO8859_9, :Windows_1254, :WI NDOWS_1254, :CP1254, :ISO8859_10, :ISO8859_11, :TIS_620, :Windows_874, :WINDOW S_874, :CP874, :ISO8859_13, :Windows_1257, :WINDOWS_1257, :CP1257, :ISO8859_14, :I SO8859_15, :ISO8859_16, :CP878, :SJIS, :Windows_31J, :WINDOWS_31J, :CP932, :CsWindo ws31J, :CSWINDOWS31J, :MacJapanese, :MACJAPANESE, :MacJapan, :MACJAPAN, :ASCII, :A NSI_X3_4_1968, :UTF_7, :CP65000, :CP65001, :UCS_2BE, :UCS_4BE, :UCS_4LE, :CP1251]

Read a file with File.read
File.read("input.txt").encoding # => # File.read("input.txt", encoding: 'ascii-8bit').encoding # => #

Read a file with File.open
result = File.open("input.txt", "r:euc-jp") do |f| f.read end result.encoding # => # result.valid_encoding? # => true

Regular Expressions
Integrated “oniguruma” engine Same basic API Much better performance Support for encodings Extended Syntax
Look-ahead (?=), (?!), look-behind (?<), (?), backreferences, etc

Named Groups
"His name is Joe".match(/name is (?\S+)/)[:name] # => "Joe"

Enumerable
Enumerator built-in, returned from Enumerable methods (and
those in Array, Dir, Hash, IO, Range, String or Struct that serve the same purposes). Added Enumerator#with_index

Map with index
%w(Joe John Jack).map.with_index do |name, offset| "#{name} is #{offset + 1}" end # => ["Joe is #1", "John is #2", "Jack is #3"]

Enumerable
reduce (inject)

[1,2,3,4].reduce(:+) # => 10
New Enumerable methods take, group_by, drop, min_by, max_by, count, and others.

take
array = [1, 2, 3, 4, 5] array.take(3) # => [1, 2, 3] array # => [1, 2, 3, 4, 5]
drop
array = [1, 2, 3, 4, 5] array.drop(3) # => [4, 5] array # => [1, 2, 3, 4, 5]

Hash Changes
Insertion order preserved
conferences = { euruko: 'Prague', scotland_on_rails: 'Edinburgh' } conferences[:railsconf_europe] = 'Berlin' conferences.each do |name, city| p "#{name} is in #{city}" end # "euruko is in Prague" # "scotland_on_rails is in Edinburgh" # "railsconf_europe is in Berlin" conferences.delete(:scotland_on_rails) conferences[:scotland_on_rails] = 'Edinburgh' conferences.each do |name, city| p "#{name} is in #{city}" end # "euruko is in Prague" # "railsconf_europe is in Berlin" # "scotland_on_rails is in Edinburgh"

Object
Added tap

thing = Thing.new.tap do |thing| thing.something = 1 thing.something_else = 2 end

Lambda Changes
Obfuscation, ahoy!
New literal syntax more flexible Not possible in { | | ... } style literals

Passing blocks
m = ->(x, &b) { b.(x * 2) if b } m.(3) do |result| puts result end # Output #6

Default arguments
->(a, b=2) { a * b }.(3) # => 6

Symbol Changes
Less sibling rivalry
Added to_proc Added =~, [] like String (to_s less needed), sortable Object#methods, etc now return an array of symbols

Indexing into
:foo[1] # => "o"

Comparing with a String
:this === "this" # => true

Fibers

“Semi-coroutines”
Similar to Python’s generators Owe method naming lineage to Lua Out of scope of the talk, but very cool For some examples, see:
http://pragdave.blogs.pragprog.com/pragdave/2007/12/pipelines-using.html (and follow-up) http://www.davidflanagan.com/blog/2007_08.html (older) Revactor project (Actors in 1.9 using Fibers + Threads) InfoQ, others...

This was really just an introduction.

Bruce Williams

bruce@codefluency.com

http://www.scribd.com/doc/2589469/Migrating-to-Ruby-19