Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

Wednesday, October 16, 2013

Wicked Good Ruby Conf Roundup

I recently returned from Boston's Wicked Good Ruby conference, and it was one of the best regional conferences I've attended.  Not only was the speaker lineup top-notch and the content itself compelling, but I was especially impressed with the attendees.

Don't get me wrong - I always have fun discussions with Ruby conference attendees.  But I've been especially impressed with the attendees here, both the New England locals and the out-of-towners that flew in.  The folks I've talked to worked in a variety of industries like healthcare, biotech, and in consumer startups.  I've also talked to folks working in really diverse teams, from one person to one hundred.

Here are some summaries and slide links for a few of my favorite presentations.


Opening Keynote
Sandi Metz

Photo Credit: @wickedgoodruby


This was a compelling keynote that drew parallels between the software engineers of today and the typesetters in the newspaper industry decades ago.  Both are stewards of the information age, so to speak, enabling the public to access huge amounts of information.  The exact skill sets of both change and are frequently made obsolete.  Sandi touched on some truly epic subjects, like getting satisfaction out of life, making every day cont, and embracing the impermanence of both career and life.  As with most keynotes, it was grand in scope and depended heavily on the stage presence of the speaker.  Sandi kept everyone engaged and I enjoyed it.


Wicked Bad Ruby
Matt Aimonetti
Slides

Matt's talk focused on the concepts of "good" and "bad" code, and what that means for developers. Matt's first point was that there is no such thing as "bad" code, as discussions of "good" versus "bad" are generally relegated to philosophy, ethics and the like.  Matt states that code simply works or doesn't.

Along the same lines, developers aren't paid to write good code, they're paid to deliver great products.  Matt advised the audience to understand what they're building - the business objectives, the timeline, the proposition value, the players, and the risk factors.  Often, the right move isn't the generally-accepted best practice.  Oftren, folks proclaiming "you're doing it wrong" don't understand the full context.

Taking a step back, Matt observed that we judge other people all the time, but we don't like to be judged ourselves.  As developers, we make rules because of what we perceive we do well, and we think they always apply directly to other people.  In other words, "you're doing it wrong because you did it differently than I did."

To sum things up, Matt recommended that we focus on the outcome while learning and improving.  As he said, don't think as much about HOW you write the code, think about WHY.  All in all, I really like this code craft-focused talk.


PEACE: Program Expertly in Corporations and Enterprises
Steven Haddox
Slides



This was a practical presentation about how to be a productive agile developer in enterprise (i.e. corporate) environments.  Steve gave a lot of great advice here, and having consulted in the enterprise myself, many things really resonated with me.  The presentation could be summed up thusly:

When working in the enterprise, fight for the following things, in order, until you run out of political capital:
  1. Agile project management (and do a one month trial if you don't get buy-in)
  2. Provisioned dev, staging and production servers
  3. Key-based authentication
  4. SCM
  5. Issue tracking
  6. Documentation/wiki
  7. Error monitoring

I'm not sure if I got the ordering exactly right, but agile project management is definitely #1.  :)



Naming is Hard
John Yurek
Slides

In this talk, John explored why naming things is difficult in programming.  To quote Phil Karlton, "There are only two hard things in Computer Science: Cache invalidation and naming things."

Through some good examples and open discussion, John brought up some great points:

  • If you can't name it, it's probably wrong.
  • If a method has one primary function, it's easier to name.
  • In longer methods, you should extract functionality into aptly-named private methods.
  • The act of refactoring and extracting code reveals that code's meaning and intent.
  • A test's name should be its justification, not a description of "what" the code does.

As with most of the Thoughtbot talks I've seen, this one had to do with "code as craft."  It was a very good mix of both actionable advice and some general topics of reflection for software developers.


Market Analytics in Eve with Ruby
Doug Alcorn
Video (older version of talk)

Doug gave a very entertaining talk about Eve online, a MMORPG with a complex virtual economy.  Eve has about 500,000 active accounts, and 30,000-60,000 players online at any one time.

Doug went over some basic information about game mechanics, types of players, and went through some interesting examples of gameplay.

Doug then went into detail on the deep player-driven economy, which is the "bedrock" of the game.  Many economists, academics, and virtual traders actually play Eve primarily for the deep virtual economy, and the game's "Chief Economist," employed by CCP Games, is actually an Economics PhD.

Doug gave lots of examples of how items are traded in-game, and then discussed the huge amount of offline data that Eve makes available to players.  CCP publishes a large REST API and allows users to scrape the in-game cache for information about item prices and upload to a third-party analytics site. This "cache scraping" is quasi-legal in the Eve world (it's not a bannable offense in itself, but it can contribute to other offenses); lots of players do it upload results to a third-party site to product accurate, real-time market data.

Doug went through some of the Ruby code he's written (namely, a Rails app) to pull in the latest market data, delete the stale data, and analyze the results.  I got a chance to speak with Doug for a bit after the presentation, and he talked in more detail about the performance of his Rails application, hosting, and the Eve community in general.  It was great to hear about Ruby in the context of online gaming, something we don't experience very often!


Towards Tooling; A Look at what is Missing from our Toolbox
Loren Segal
[Slides Unavailable]



In this talk, Loren discussed tooling in the Ruby language community.  He first discussed tooling at a high level, talked briefly about tools that the Ruby community is good at, and finally explored areas where the Ruby community could improve.

Loren's observation: Humans have basically gotten to where they are because of their intellect and tooling.  Tooling allows humans to become more efficient and build off the successes of previous generations.

Deployment, ops, testing:  These are very good in Ruby.

Visualization, debugging, linting, static analysis: Ruby could be much better.

Loren pointed out that debugging front-end web development in say, Firebug or Chrome inspector, is inherently visual, and works well.  Visual Studio has good tools like this, letting programmers visualize the entire call stack and easily trace execution.  Ruby needs better tools to this end.

Loren briefly discussed some code complexity analysis tools, such as reek, flog and flay.  These detect "code smells" but not common errors.  This is in the domain of static analysis, which is lacking in the Ruby world.


Overall

This was a great conference, and even as a local, I'm continually impressed with the skills of developers in the New England area.  If you have any of your own summaries or links to video from WGR Conf, let me know!

Wednesday, October 2, 2013

Upgrading Legacy Applications: Ruby 1.8 Pitfalls

When dealing with large, long-lived enterprise apps, the upgrade cycle is often much slower.  Because these applications aren't always under active development, the prospect of "long-term support" releases becomes more important.

We recently upgraded a client app from Ruby 1.8.7 to Ruby 1.9.3, just as support for Ruby 1.8.7 was ending.  We ran into some "gotchas" while upgrading, so perhaps these will help other developers in the future.

In general, the incompatibilities between Ruby 1.8 and 1.9 are well-known, but we discovered a few lesser-known issues during this upgrade.

1. Array#to_s

In Ruby 1.8, calling to_s on an Array is equivalent to calling join.

In Ruby 1.9, calling to_s on an Array is equivalent to calling inspect.


This seems like a minor change, but it is significant.  There are many Ruby 1.8 libraries that will display arrays directly to users via to_s, assuming the array will be suitable for display directly to an end-user.

If that code is run against Ruby, 1.9 the displayed array will include both the brackets and commas, usually making it unsuitable for end-user display.

2. Symbol#to_i gone

As of Ruby 1.9.2., symbols are no longer internally represented as integers and Symbol#to_i was removed (thanks to andrewjgrimm for pointing this out).  Thus, if you call string_object[:symbol], it will use the symbol's integer representation to reference an element under Ruby 1.8.

3. Creating Hashes

In Ruby 1.8, you can actually create a hash by putting an list of keys and values directly in the curly braces. In Ruby 1.9, that doesn't work.

KEY TAKEAWAY

Backwards compatibility in languages is important, especially when building enterprise applications.  Even if a seemingly-arbitrary change looks like a net win for program correctness, it can cause problems in legacy software.

For example, consider the following code:

Let's say you have a bug in method_that_returns_a_hash, and it sometimes returns a String instead.  Under Ruby 1.8, that bug might be completely innocuous, because address_map[:canada] would still return nil, and your program could still execute correctly.  Under 1.9, that would raise an error.

What other obscure incompatibilities have you encountered while upgrading legacy software?

Thursday, January 3, 2013

Presenting at LA RubyConf 2013!

I'm very excited to announce that my proposal was accepted and I'll be presenting at the Los Angeles Ruby Conference on February 23, 2012.

I'll be giving a talk, "Python for Ruby Programmers," to familiarize Rubyists with Python and give them a better sense of Python's relative strengths and weaknesses.  We'll talk syntax, maintainability, and practical applications.

More information coming soon!

Friday, November 2, 2012

RubyConf Roundup: Day Two



I just finished the second day of RubyConf 2012 in Denver.  There were more great talks and a ton of information to digest!  Check out the following for synopses of some of the talks I attended.


RUBY VS THE WORLD
Matt Aimonetti
Slides

Here, Matt gave us a tour of three modern programming languages: Go, Clojure and Scala.  Matt discussed strengths, weaknesses and applications of each, and described them in relation to Ruby.

Matt compared programming languages to human languages, in that the way languages are designed affects our worldview and the way we solve problems.

Bad ways of evaluating a language:

  1. Looking at "hello world" only
  2. Looking purely at syntax.  This might give you a feeling about the language or its aesthetic, but no deep insight.

Good ways of evaluating a language:

  1. Looking at the language's philosophy
  2. Looking at use cases for which the language was designed
  3. Trying to look at the language with new eyes, like it's the first language you learned


GO:
Compiled, structural, typed, object-oriented, and functional.
Learning curve: normal.
Has the concept of a pointer, so C experience helps.

Matt showed a Go use-case with concurrency, walking through a short program to fetch three URLs at once.

Matt created a function that fetches URLs and created a channel (a broker for concurrent tasks) to do the work.  He then created a "go" function, which runs asynchronously and fetches the URLs.  Finally, Matt implemented a for loop where you (a) ask if there's anything ready in the channel, (b) get it, if it's there, and (c) add it to an array.

Philosophy: Go tries to be the new C. It's not a big language and it's easy to remember.

What's bad about it?  It can be too low level, it doesn't have great garbage collection, and it has "weird" conventions at times.

What's good about it? It has simple specs, modern standard libraries, great concurrency support, very fast compilation, flexible code organization, a simpler take on OO, functional programming features, good error handling, and good documentation.

CLOJURE:
Clojure is a compiled, dynamically typed, functional, mostly object-oriented language.

Learning curve: difficult.

One use case: data processing.

Philosophy: Clojure is "the pragmatic scheme." Scheme and Lisp are great, so Clojure adds more object-oriented features to make it more useful in the real world.

What's bad?  It's not very simple, not always consistent, one needs to know lots of functions and macros, it's not really web-focused, it can cause a "brain stack overflow," it can be a difficult mental context switch, and it has cryptic error stacks. (whew!)

What's good?  Matt didn't go into this in great detail.  He didn't really sell this one.

SCALA:
It's the closest of these languages to Ruby, according to Matt.  It's both OO and functional. It's compiled and can have either static, inferred or dynamic types.  Learning curve is moderately difficult.

One good use case, according to Matt, was for Service Oriented Architecture, or whenever you need a more "enterprisey" Ruby.

Scala has lots of familiar elements if you're coming from a Ruby background.  It has enumerable objects, anonymous methods, default method parameters, metaprogramming features like method_missing, duck typing, mixins, and a focus on testing.


Philosphy:  Scala is like Ruby, minus the scripting, plus static typing.  Matt called it "the academic version of Ruby."


What's good?  Scala has a focus on tests, inner methods, lazy evals and streams, a great garbage collector, good performance, and good tool/IDE support.  It's it's easy to get started, has inferred types, uses flexible functional approach, includes modern concerns like parallelism and pattern matching, and has a very active community.

What's bad?  According to Matt, Scala has a huge surface, a stiff learning curve, "abused" OO syntax, and poor documentation.

OVERALL:
How did this language exploration affect how Matt writes Ruby?  Matt noted that Ruby is as functional as it is object-oriented,  and these two paradigms are complementary.  In Matt's view, functional programming should be used to extend your program with new operations.  Object-oriented programming should be used when the data in your program evolves.


HOW TO BUILD, USE AND GROW INTERNAL TOOLS
Keavy McMinn
Slides

Keavy, who works in a large distributed team at Github, discussed (a) use-cases for developing internal tools and (b) best practices for using internal tools.

Central theme: Create the culture you want at your organization through internal tools.

Most people use and abuse internal tools, like using email threads for "everything."

Keavy discussed three use-cases for internal tools, each brought about by someone's "pain."

PAIN #1:
"I don't know who is working on what."

Keavy showed how Github built a simple social tool where you can say what you're working on.  "I am next shipping X."

Keavy observed that this visibility makes developers more motivated to do a great job on projects, and added a sort of "friendly competition" dimension to communication.  "We see awesome get shipped, so we want to ship awesome too."

PAIN #2:
"I feel disconnected because I am remote."

I was surprised to see that about half of the audience works remotely when Keavy asked!


Keavy said that Github deals with this, in part, by not "abusing" tools that require everyone to be in the same place at the same time, like physical meetings and phone calls.  Github employees are spread out across many different time zones, so coordinated meetings can be tough.

On the other hand, one audience member noted that these distributed practices (email, pull requests, tickets, social feeds) can be much more time-consuming than coordinated meetings, because of the long feedback cycle.


Github has also implemented "fun" tools to help folks feel connected.  They have a company music feed where everyone can listen to the same music, and everyone can rate/select songs that are played.  Employees can even change the volume!

Keavy noted that digital communication can be tough. When the message is neutral, it's usually perceived as negative over the Internet.  Positive language is generally much more powerful.

Keavy mentions: A big challenge with distributed teams is that people have a tendency to "hide" until their work is  complete and "shiny," and then show their work after.  This is usually bad for both company culture and project momentum.  Committing early and often works much better.

Keavy calls Github's paradigm "cooperation without coordination," as most work is asynchronous.

PAIN #3:
"I don't like {something that's being done in the company}."

Keavy said that teams should always be giving and receiving feedback on internal processes.  ALWAYS.  Don't just "go with the flow" in terms of internal tools/processes; think of ways to constantly improve them.

Github has an "ideas" feed, where employees are always suggesting ways to work better together.  They receive over 30 ideas per month and even more comments on those ideas.

If there's a tool you're using for everything, that's a red flag.  It's hard to opt out of long email threads, but not as hard to opt out of a ticket you're watching, a pull request, or a more specific tool.


ARDUINO THE RUBY WAY
Austin Vance
Slides

Austin gave an overview of his experiences with Arduino, and discussed the use of Ruby to control Arduino devices.

Arduinos ship with a basic IDE and a "stock" C++-based DSL.  It lets you compile and verify code.

Austin showed us RAD, a system for Ruby Arduino Development.  Debugging is hard in RAD, and it's not under active development, so he avoided this.

Austin noted that Node.js works really well with Arduino, since Arduino devices are asynchronous as well as Node.js.

He also showed us Duino, a C++ library you put on the Arduino that acts as a service.  You can use node.js to talk to service, just like any web service, and abstract away some of the hardware details. Austin wanted to write Ruby, though, so he created a Ruby library to do what Duino did.

Goals of this library: Fully tested, easy to extend, great documentation, zero startup time, fun.

Architecture:
There's a "Board" class that's the programmatic representation of the Arduino.  It has pins, it has I/O, it knows how to talk to and read things. One thing it doesn't do is communication, though.

The "TxRx" (domain-specific term) class handles sending and receiving messages.  TxRx functionality is injected into the board, so you can write an adapter for Wifi or Bluetooth  as long as you adhere to same public interface.

There's a "Components" module that sets up pins, makes sure the board is there, etc.

The architecture involves passing functions around, as procs, so the system can respond to future events like button presses.  You can pass event-specific data into the procs, like the magnitude (distance) of a proximity sensor event.

Finally, Austin hooked all of this up to a Sinatra app, and used it to control his Arduino-based t-shirt cannon.  He let the audience interact with the app through their laptops, fire t-shirts, and much fun ensued!


INSIDE RUBYMOTION
Rich Kilmer
[no slides yet]

Rich showed us RubyMotion, a system that lets us write Ruby Code, compile it to Objective-C, create iOS apps, and ship them.

EverClip, for example, is built completely in RubyMotion.  It makes use of 3rd-party objective-C libraries, won an award, and is for sale in the app store.  Upshot: It is possible to make money with RubyMotion.

RubyMotion is like Ruby, but statically compiled.  It features a terminal-based toolchain, and you can keep using your favorite editor.   You can use any Ruby feature, including metaprogramming ones, except eval.

Rich showed us how much more complex and verbose an Objective-C "hello world" app is compared to Ruby.  He then showed how we can actually write OpenGL code in Ruby, using C constants and C libraries directly.

RubyMotion starts with Ruby source code, creates an abstract syntax tree, as usual, and then compiles it down into LLVM portable assembly language.  Objective C classes map one-to-one with Ruby classes.

Rich showed us how we can debug in RubyMotion, do the typical "breakpoint" stuff, debug, and see where we are in the Ruby code.  He then showed us how testing support is much more robust in RubyMotion than in Objective-C.

Interestingly, Rich surveyed the audience and found that almost none of the Objective-C developers wrote automated tests for their apps!

Finally, Rich showed us the "console," which looks like ERB, but dynamically compiles your Ruby code, sends it to the iOS emulator, and returns the result.  In other words, you can fetch a button object, change the text, and see it on the simulator in real time!  Lots of "oohs" and "aahs" from the audience there.

When taking audience questions, Rich couldn't come up with a single use-case where vanilla iOS development would be preferable to RubyMotion.  I'm a bit skeptical about that, as mobile developers always talk about how they need to "go native," but I enjoyed this talk nonetheless!

Questions?  Comments?  Let me know!  Read more about all the talks here.

RubyConf Roundup: Day One



I just arrived in Denver and finished up day one of the always-excellent RubyConf.  I met a many smart engineers and saw some really informative presentations!  Here are some synopses of the talks I attended.


MATZ'S KEYNOTE
Yukihiro Matsumoto
Slides

I always enjoy Matz's keynote talks.  As the face of the Ruby programming language, Matz has a great "zen" approach to talks, where he speaks generally about programming for fun, personal fulfillment, and making the world a better place.

Matz talked a lot about finding motivation for projects, how motivation is hard to come by, and how it's the single most important factor in doing a good job on something.

Matz asked, "how do you become a language designer?"  Most folks in the audience had not designed or implemented a programming language.  Matz noted that programming in general is very similar to language design:  As a programmer, you design code, APIs, and interfaces.  "Programming is designing DSLs."

Matz noted that the world is full of bad designs.  He showed how he "hacked" shoelaces by super-gluing them so they wouldn't become untied.

Matz's approach to writing software, according to this talk, is to get inspired and "make it happen."

Matz then talked more specifically about the Ruby language and reflected on the scope of the project.  Starting as a pet project in 1993 (almost 20 years ago!),  it became hugely popular and Matz couldn't really process it while it was happening.

Matz noted that Ruby 2.0 will be "faster, more reliable, more tested, and more fun to use."  He gave a quick overview of Ruby 2.0's features but didn't go into detail (see below for that presentation).

Matz ended the talk by telling programmers to "be motivated, get coding, reinvent the wheel, and make the world better."


ABSTRACTING FEATURES INTO CUSTOM REVERSE PROXIES
Nick Muerdter
Slides

In this presentation, Nick talked about using evented architecture to implement reverse proxies via (a) rack-reverse-proxy and (b) EventMachine Proxy.

Performance:
rack-reverse proxy (RRP) adds much more overhead than EM Proxy for big data requests.  RRP buffers everything in memory, and that is the primary performance bottleneck in the system.

EM proxy deals with data in chunks, and as such, it's much more flexible when dealing with large amounts of data.  Nick noted that EM proxy is more flexible overall.

Some use cases for reverse proxies like these:

  • error handling
  • web page manipulation
  • inserting a standard JS analytics statement in all responses
  • implementing email servers
Content-length: You need to deal with content-length if you're modifying the response for client, and must keep it in sync with the actual content.

Gzip responses can also be problematic for reverse proxies.  You need to buffer the entire response to serve the gzipped content, since you can't break it up into chunks.

Nick noted that there's currently a "web services bonanza" in the federal government.  There's a big push toward interoperability, and many organizations are publishing new web services.

Nick's central theme: Look at different ways to architect your software.  Now that you can implement reverse proxies in Ruby, it's easier for them to perform advanced functionality like connecting to the database, communicating with APIs, etc.


SERVICE ORIENTED ARCHITECTURE AT SQUARE
Chris Hunt
Slides

Chris works at square, which lets anyone process payments easily.  They've made apps for Android and iOS, and have a central Rails API.  Creating a Service Oriented Architecture (SOA) was something their team had to do and had to become better at.

The Square team kept adding features to their product over time, have hundreds of model/controller files in their central Rails app, and have hundreds of thousands of lines of code.  They needed SOA, a better way to scale their growing architecture.

The SOA Creed, like that of UNIX, is to do one thing and do it well.  Usually, the idea is to make a new service for a group of new, related features, unless they relate strongly to existing features.

All of Square's SOA components run on JVM platforms (Java, JRuby, Jython, Closure, etc.).  They can deploy everything via Java, and this normalization is a big win for them.  New components simply require the JVM, and they can run on any server in any data center.

Chris walked us through a "boilerplate" service, which set up documentation, testing, code quality metrics and more for new services.

Chris showed how his team uses FDoc to enforce documentation across services.

A big inspiration for Chris was the book Growing Object-Oriented Software, Guided by Tests.

To test, Chris' team makes fake version the other services, usually in Sinatra, so he only needs to describe the service endpoint.  He uses the tool foreman to boot up fake services and use them for development and test environments.

Square uses cane to enforce code quality standards across different teams and services.  If code quality or style isn't up to snuff, it actually breaks the build (awesome!).

Chris uses cubism.js to visualize time series data from errors and other activity.  He uses the enterprise tool splunk to manage log files and track, say, a payment id, as it goes through different services

Security:  Square uses SSL certificates for mutual authentication between services, as opposed to one-way SSL on websites most of us are familiar with.  Every service has an SSL certificate, and each one has an organizational unit (service name).  This lets their team ensure that a service is authorized for a given action, implemented as a before_filter in Rails controllers.


RUBY 2.0 (ON RAILS)
Akira Matsuda
Slides

Ruby 2.0 is scheduled for release in February 2013.  Akira, on the Ruby core team, walked through the new features.  Lots of this information is available elsewhere, so I'm going to punt on some of this stuff.

Ruby 2.0 is 100% compatible with current stable version of Ruby (o rly?).  The feature freeze was one week ago.

  1. Module#refine and Kernel#using let programmers "monkey patch" code while keeping the scope constrained to the redefining module.  This makes monkey patches much safer and doesn't pollute the global scope. Kernel#using lets you apply that refinement to a specific scope.  Akira went through some example by refactoring ActiveRecord and ActiveSupport to use refinements.  Read more here.
  2. Module#Prepend lets programmers include functionality from modules into a class, similar to include, but now methods from the module take precedence over those in the class.  This is a much safer alternative to alias_method_chain, found in Rails, and other monkey patching techniques.  Read more here.
  3. Enumerable#lazy lets you perform actions on enumerable objects without evaluating the entire collection.  Akira showed how we could do some processing/evaluation on a range from 1 to infinity, or on a list of all dates, while completing in a reasonable amount of time. Read more here.  
  4. Keyword args.  In Ruby 2.0, you can easily accept hash keyword arguments with default values.  This lets you specify and validate hash keyword arguments and provides a cleaner way to deal with multiple hash parameters (like options and html_options in Rails' button_to, for example).  Read more here.



ZERO DOWNTIME DEPLOYS MADE EASY
Matt Duncan
[no slides yet]

Matt Duncan went over some good techniques for reducing downtime during web application deployment.

Matt suggested developers look at a traffic graph and decide what trade-offs need to be made for reducing deployment downtime.  Can you run a migration when traffic is low, if it won't affect many users?  Can you throw money at a faster database to mitigate the situation.

Matt recommended you separate code update deployments from database migrations, the latter of which he calls a "database deploy."  He suggested folks try:

  1. Having an initial migration, just to add new fields, as that introduces little to no downtime
  2. Have a separate rake task to update records as needed, outside of the migration-induced database lock

He suggested developers use "CREATE INDEX CONCURRENTLY" a Postgres feature, to create DB indexes without causing downtime.  (Not using Postgres?  You're out of luck!)

When updating job queue code, he warned developers that "queues are almost never empty," and to take that into account during deployments.

Matt recommended that developers set version numbers on all external services and make it easy to "roll back" external services in case of failure or errors during deployment.

Matt noted that in many cases, developers can disable a feature while running an complex/expensive deployment to update it.  Say you need to deploy an update to search backend like SOLR, for example.  Perhaps you can (a) deploy a change to hide the search bar in your application, (b) update the search service nicely,  and (c) add the search bar back.  This seemed a bit crazy to me and would require lots of extra effort.

Matt recommended that folks check out rollout, a library to gradually roll out services to a certain percentage of users at a time.


REFACTORING FROM GOOD TO GREAT
Ben Orenstein
[no slides]

Ben walked us though several examples of refactoring Ruby code.  Ben showed some tell-tale "code smells" and applied advanced object-oriented techniques to refactor the code.  IMO, talks like this really show the maturation of the Ruby ecosystem over the past few years.

Ben demonstrated:

  1. factoring out functionality into private methods so developers didn't have to read it right away
  2. recognizing when classes have "feature envy," or lots of functionality related to a different class
  3. using a single concept (like a range) to represent multiple entities (like a start and end date)
  4. reducing coupling between systems
  5. creating a situation-specific null object so his code could "tell, not ask"
  6. depending on abstractions for related functionality, making it easier to mock and test

Ben also showed us examples of good times to refactor:

  1. All the time :)
  2. When you have "god objects," or objects that try to do everything.  In Rails apps, this is usually (a) the user model and (b) the central object related to your specific app (like "Order" for e-commerce apps).
  3. When you see high-churn files, or files that change often.
  4. When you have lots of bugs surrounding a specific feature. 

BUILDING MODULAR, SCALABLE WEB APPS? OF CORS!
Michael Bleigh
Slides

Michael talked about CORS, or Cross-origin resource sharing.  Background information available here.

CORS:  As long as other domains implement the protocol, users on one server can get resources from other servers.  Often, this means we can make an ajax call to a different server.

"Like most good things," this doesn't work in IE < 10.

With CORS, your site has access control headers that show whether a given domain is allowed to make ajax requests.  You can specify acceptable domains, or use a wildcard to allow all domains.

There's an additional "options preflight request," triggered when the request is not a simple GET or  has custom headers.  This helps to prevent cross-site scripting and the like.  The preflight response shows access-control-allow-origin or access-control-allow-methods headers, telling the client whether it's allowed to make the request.

CORS disadvantages:

  1. Initial complexity
  2. Cross-service communication
  3. Lack of framework


Michael recommended that Rubyists check out the rack-cors gem.

Michael argues that using CORS for public APIS is a HUGE win, because it's a lower barrier to entry for external developers.  You don't need a server to make requests to your API; it can all happen in the browser.  A developer could implement a locally-hosted HTML file that makes requests your API.  In other words, it's roughly the same burden on you, but much less on third-party developers.

Michael also walked through some security concerns in terms of handling authentication for public CORS-based APIs.  For example, you can't count on secrets since everything is exposed on the front end, and you still want to identify the requesting application.  Github's solution is to only allow CORS requests from domains of registered applications.


Questions?  Comments?  Let me know!  Read more about all the talks here.

Monday, April 4, 2011

Redmine-lite Released

I recently released redmine-lite, an easy-to-install fork of Redmine 1.0.3-stable, a project management and issue-tracking tool.

Redmine-lite has smart conventions that help you set up your instance quickly and painlessly.  In fact, you can set it up and deploy it on your server in under five minutes.  Out of the box, it's set up to use the sqlite database, the thin web server, and Gmail for outgoing messages.  

Redmine-lite is ideal for developers whose organizations require them to host issue-tracking software locally, but don't have much time to set up and administer a system.  Redmine-lite was the result of an enterprise client project.  At the time of writing, we're using this for a project with about 8 users, and it's currently tracking about 2-300 issues.


Check out the 90 second screencast!
Dependencies:  gitbundlerrvm.




Tuesday, February 15, 2011

MagicRuby Roundup

Last week, I attended the MagicRuby conference in Orlando.  Aside from all the content in the talks, I learned three important things:
  1. Rubyists are always trying something new and interesting.
  2. Disney World is a great place to hold a conference.
  3. Orlando has a fun and enthusiastic Ruby community!
I saw a lot of great talks at this conference.  I'm attempting to condense 30+ pages of notes into only the most important information.  I'll tell you (a) where to find slides/video, (b) who I think should check out each talk, and (c) what I think the most important points are.

This doesn't include every talk, but it includes most of them.

----------

Cultivating Cucumber  (Slides)
Les Hill, Hashrocket

Who should check it out?
  • Developers interested in improving TDD and BDD practices.  
  • Developers unsure of whether to use Cucumber.
Short take:
  • Great summary of the features of cucumber:  Hooks, tags, steps, and more!
  • Good explanation of Cucmber's strengths (like the use of natural langage) and its weaknesses (like the need to maintain all those regexes)
  • Good discussion of best practices for organizing and refactoring cucumber suites.
  • I wish there was more discussion about the types of projects where cucumber is most useful.

----------

Geospacing Your Ruby (Slides)
Peter Jackson, Intridea

Who should check it out?
  • Developers of spatially-enabled apps
  • Developers working in government, urban planning or environmental modeling.
  • Database Administrators (for those of you in the enterprise)
  • Geography/map buffs.
Short take:
  • Great overview of spatial terms, geometry, map types, etc.
  • Great overview of existing database and front-end tools for spatially-enabled apps.
  • Good suggestions for interesting spatial data to model and useful ways of displaying it.

----------

Loving your Customers, Loving your Peers (No slides available)
Alan Johnson, Carsonified

Who should check it out?
  • Technical people who deal directly with customers
  • People who want to improve the reputation of the Ruby community
Short take:
  • A "feel good" presentation, rife with humorous anecdotes and pop culture references.
  • A good reality check for developers who are quickly dismissive of non-ruby technologies, Microsoft, etc.
  • Lots of great suggestions on how to treat customers better, how to empathize with customers, and how to enjoy your job more.

----------

Code is not Enough (No slides available)
Gregg Pollack / Caike Souza, EnvyLabs

Who should check it out?
  • Entrepreneurs
  • Freelancers
  • Software development shop owners
  • Employees of small companies
Short take:
  • Good commentary on many important engineering management concepts:  Setting expectations, delegating tasks, etc.
  • A good discussion on software development as a craft vs an art.
  • Good suggestions for developers, like "don't be afraid to ask for help" and advice on how to "get in the zone" while programming.
  • Great advice on creating a culture of learning at your organization (especially the "book club" suggestion)
  • Good insight into effective networking and "making friends rather than sales"
  • Asserted that developing a product for another company is more difficult than developing and launching your own product (I don't necessarily agree)

----------

Exceptional Ruby (Slides and More)
Avdi Grimm

Who should check it out?
  • Just about any Ruby developer.
Short take:
  • Good review of exception syntax and handling in Ruby.
  • Great discussion on when to use exceptions in the first place ("exceptions are for exceptional situations")
  • Review of many design techniques for handling and managing exceptions
  • Reviewed some common software design pitfalls related to exceptions.

----------

What happened to Desktop Development in Ruby? (blog post)
Andy Maleh, Obtiva

Who should check it out?
  • Developers interested in desktop applications
  • Developers interested in the current state of desktop application programming in Ruby.
Short take:
  • Great review of current desktop development frameworks:  shoes, wxWidgets, Limelight, Glimmer
  • Excelent insight into what's wrong and what's right with each framework.
  • Great perspective on what makes a well-designed desktop app framework.

----------

Keynote (No Slides Available)
Dave Thomas, Pickaxe Author

Who should check it out?
  • Dave Thomas fans
  • Project managers and developers looking to improve software development methodologies.
Short take:
  • Great review of what it really means to practice "agile" development.
  • Insightful  recursive algorithm for software development:  Where do we want to be?  Where are we now?  How do we improve our position? Repeat. 
  • Good use of a one-wheel balancing robot as a metaphor for prioritizing and executing incremental software changes.
  • Advocated the "ten second audit" for developers:  Why am I doing this?  Does it have to be done this way?  Does it have to be done at all?
  • Insightful, humorous commentary on overzealous cucumber evangelists and constantly-changing tools in the Ruby community. 

----------

Crank up your Apps with Torquebox (Slides and Video)
Jim Crossley, Red Hat

Who should check it out?
  • Enterprise developers who want to work with Ruby but must develop in a Java ecosystem
  • Developers challenged with building scalable, distributed web applications.
Short take:
  • Good overview of everything Torquebox:  Configuration, JBoss, messaging, queues, processors, services, scaling techniques, and more.
  • Good discussion of use-cases for Torquebox, its performance, and potential future changes.

----------

How I Lerned to Stop Worrying and Love the Cloud (Slides)
Wesley Beary, Engine Yard

Who should check it out?
  • Developers currently using or interested in cloud-based infrastructure.
  • Anyone overwhelmed by the choice of cloud providers.
Short take:
  • Great overview of Fog, a vendor-agnostic cloud interface that works with many popular providers, such as EC2 and Rackspace.
  • Discusses many good use-cases for Fog.
  • Helpful, tutorial-style explanation of how to use Fog to interface with a cloud provider.

----------

Documentation is Freaking Awesome (Slides and More)
Kyle Neath, Github

Who should check it out?
  • Open-source authors.
  • Any developer who might, at some point in the future, hand off their project to someone else.  :)
Short take:
  • Very straightforward, "common-sense" talk about why documentation will help your project.
  • Discussed many useful ways to improve documentation, covering everything from the README to RDoc to Yard to "Having an awesome web page."
----------

Please let me know if there are any errors, of if you can point me to any slides that are currently missing!

Thursday, November 4, 2010

Oracle on Rails: Can Proprietary and Open-Source Play Nice Together?

We're starting a new enterprise Rails project at Panoptic Development (that's right, enterprise Rails), and we're using the Oracle database. Yes, we all know that Rails plays best with other open-source databases like PostgreSQL, but sometimes development teams don't have the luxury of choosing the database.

The upshot of all this? We'll hopefully be contributing some articles and open-source code to help other developers work with the proprietary, enterprise behemoth that is the Oracle database.

I've started with a quick fork of Raimonds Simanovskis' useful rails_3_oracle_sample application, adding some documentation that helped me get things started.

Raimonds seems to be working harder than everyone else to integrate Oracle with Ruby on Rails, so check out his excellent blog.

Most Rails developers work in small, agile teams without a dedicated DBA, and that's often quite different from the workflow in large organizations using Oracle. Here's one of Raimonds' presentations (from three years ago!) that helped get me into the Oracle mindset:


Stay tuned for more updates.

Tuesday, August 31, 2010

Turn your Android Phone Into a Remote Spy Camera with Ruby in 15 Minutes

Update 8/20/12: This project is over two years old at this point, and I am no longer working on it.  This was a proof of concept and, unfortunately, I am no longer able to provide support to readers with questions.

It's been a great year for Ruby on Android, but no one knows it.

Sinatra running on a Motorola Droid

You can start writing Ruby apps for Android devices TODAY.  You don't need to install any SDK, you don't need to install some giant Eclipse IDE, and you certainly don't need to write any Java.

Some of you may have heard of Ruboto, but Damon Kohler and the team at android-scripting have been quietly improving SL4A over the past year, adding tons of features and improving stability.
Scripting Layer for Android (SL4A, formerly known as Android Scripting Environment or ASE) brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreters directly on the Android device. These scripts have access to many of the APIs available to full-fledged Android applications, but with a greatly simplified interface that makes it easy to get things done...  Python, Perl, JRuby, Lua, BeanShell, JavaScript, Tcl, and shell are currently supported, and we're planning to add more.
There's even support for distributing  programs as APKs, so the implementation language and dependencies are totally transparent to users.

We'd love to run some simple Ruby scripts on Android, but what about running a complete, albeit simple, application?  Will it work?

Most Rubyists use Ruby to build web applications, so let's run with that.  Let's build a spy camera app, so I can figure out who's been stealing ink cartridges from our office.  The app should (a) show me a snapshot of what the camera currently sees and (b) update that snapshot on demand.

We need a simple, lightweight ruby framework to use. Sinatra is very easy to use and should even be able to run on older Android devices.

Similarly, we need a simple, lightweight, pure ruby web server.  WEBrick is pure ruby, part of the standard library, and fast enough to run on Android.  Works for me!

First, let's work from our development machine (i.e. laptop).  No need to touch the phone just yet.

Start a New Sinatra Project



But wait!  What about Sinatra itself?  We can't easily install rubygems on our Android phone, so we'll have to vendorize Sinatra and all dependencies and ship them with our application.  Since we'll be running JRuby on Android, we can't use any libraries that have native C extensions or are otherwise JRuby-incompatible.

Make Directories for Gems and Snapshots



Vendorize your Gems



Create the App

Create a file called spycamera.rb in the project directory.

First, let's set some constants for the important directories in our application. When running apps under SL4A, we need to be very explicit about directory paths.



Let's update our load path, so JRuby can find our vendorized gems.


Next, we'll load Sinatra.  We'll have to explicitly load rack first, to avoid uninitialized constant errors under SL4A.



Finally, we require the Android API interface, available under SL4A, and initialize an Android object.  This will allow us to make API calls, like one that tells the camera to take and store a picture.




Now, let's create a very simple HTML template.  The template should just display the latest snapshot, which we'll be saving to public/latest.png.  If I click on that snapshot, it should take a new snapshot and refresh the page.



Finally, create a tiny Sinatra app that takes a picture, saves it, and renders the template.



Install (Deploy) The App

Now you can finally use your phone!  Grab that Android device and install SL4A (r1 APK available here).  Run SL4A, go to the interpreters menu, and install JRuby.

Once JRuby is installed, it's time to deploy your application to the phone.

Connect your phone to your development machine via USB, and simply copy the contents of your app to SL4A's script directory on your phone.  There may be some sample ruby scripts left over from the SL4A install; you can delete them if you like.

Copying the project contents onto the deivice.

At this point, just run spycam.rb from SL4A and you're good to go!

Starting the Sinatra app from SL4A

Place your newly-activated spy camera somewhere, hide in your office/cube, start your web browser, and navigate to http://ip.address.of.phone:4567.  You can do this from inside your local network via wifi, or, carrier permitting, over 3G.

Happy spying!

Further Reading
Check out my open-source project, Broadcast, on Github.  It's a more refined, general-purpose embedded web app for Android.  It allows for further remote monitoring and control, such as location tracking, remote text-to-speech, and remote file management over HTTP.  


The source code for the spycam app is available on github here.


Check these out, too:

Tuesday, August 24, 2010

Broadcast Presentation at RIRUG

Slides are up from my August presentation at RIRUG. I'm really excited about this software; more posts to follow shortly!

Friday, February 12, 2010

Fabric - A Deployment Tool for Rubyists and Pythonists Alike

If you're coming from the Ruby/Rails world, the industry standard tool for deployment is clearly Capistrano

In some cases, though, using Fabric might make more sense.  If you've got a simple web app and want to try something different for deployment, have a look at Fabric. It's a terse, lightweight Python deployment tool and a good alternative to Capistrano. Most importantly, it's SUPER EASY to learn and you don't need ANY Python experience.

I like how Fabric's tutorial shows a version-control-agnostic deployment pattern. The fabfile is part of the project we want to deploy, and whatever is in our project directory will be deployed. With this pattern, Fabric doesn't need any information about our version control system or repository.

For example, I use git for most of my projects.

If I'm running the master branch on my development machine and want to deploy master, I just run
$ fab deploy
What if I want to deploy my release branch instead of the master branch? I just do the following:
$ git checkout my-release-branch
$ fab deploy

Super easy.  We can manage the code we're deploying with the tools already built in to our version control system; we don't have to implement those controls again with our deployment tool.

Installing Fabric on Ubuntu 9.10
$ sudo apt-get install python-setuptools
$ sudo easy_install fabric

Wow, that was easy.

Thursday, October 15, 2009

Sharing Model Code via Modules

Recently, I worked on an embedded Rails application where there were two models representing network devices.  The models were quite different, but nonetheless, both had host and name fields, and there was some shared functionality.  Here's an example:

class NetworkVideoDevice < ActiveRecord::Base
  require 'ping'


  def responds_to_ping?
    Ping.pingecho host, 1.0
  end

  has_many :live_streams
 
  validates_uniqueness_of :host

  validates_presence_of   :name

  named_scope :ordered_by_host, {:order => "host"}
end

class NetworkAudioDevice < ActiveRecord::Base
  require 'ping'

  def responds_to_ping?
    Ping.pingecho host, 1.0
  end

  has_many :live_streams
 
  validates_uniqueness_of :host

  validates_presence_of   :name

  named_scope :ordered_by_host, {:order => "host"}
end

At this point, developers may be aware of the code smells.  Maintaining the same functionality in two places is error-prone, hard to debug, and puts an unnecessary burden on developers.  In the pre-Rails 2.0 days, I saw many developers using Single Table Inheritence to share functionality between models.  As Rails developers' familiarity with Ruby increased, though, I've noticed developers taking advantage of Ruby's Modules for solutions to problems like this.

First, let's factor out the common method, responds_to_ping? into a module.  Since this module will only be used by Active Record models, I'm going to put it directly in the app/models directory so I don't even have to require it anywhere.  Now, the code looks like this:

# the newly-created module:
module NetworkDevice
  require 'ping'

  def responds_to_ping?
    Ping.pingecho host, 1.0
  end
end

class NetworkVideoDevice < ActiveRecord::Base
  include NetworkDevice

  has_many :live_streams
 
  validates_uniqueness_of :host

  validates_presence_of   :name

  named_scope :ordered_by_host, {:order => "host"}
end

class NetworkAudioDevice < ActiveRecord::Base
  include NetworkDevice

  has_many :live_streams
 
  validates_uniqueness_of :host

  validates_presence_of   :name

  named_scope :ordered_by_host, {:order => "host"}
end

Now, if we want to change that ping timeout from one second to two seconds, we only need to change it in one place.

This is a good start, but we can take our refactoring even further. 


Sharing ActiveRecord Functionality via included and class_eval

We also do the same validation on some fields, and we have the same named_scope call in both models.  Let's stick those in the module, too!  Now, NetworkDevice looks like this:

module NetworkDevice < ActiveRecord::Base
  require 'ping'

  def responds_to_ping?
    Ping.pingecho host, 1.0
  end

  has_many :live_streams
 
  validates_uniqueness_of :host

  validates_presence_of   :name

  named_scope :ordered_by_host, {:order => "host"}
end

But wait!  Try to start your application, and it barfs!  What happened?
NoMethodError: undefined method `has_many' for NetworkDevice:Module

Our NetworkDevice module doesn't know anything about ActiveRecord methods like has_many, so when Ruby tries to evaluate it outside the context of an AR::Base-descended class, it doesn't work. 

The solution? use Module's included method and Class's class_eval method.

included, a class method available to modules, lets us defer funcionality until the module is included somewhere.  We simply tell Ruby to evaluate some code in the context of the including class, which will descend from ActiveRecord::Base. 

class_eval lets us define or call class methods on the receiver on the fly.  In this case, we'll want to call some ActiveRecord::Base class methods, like named_scope.

Sound confusing?  Let's see the new code in action:

module NetworkDevice < ActiveRecord::Base
  require 'ping'

  def responds_to_ping?
    Ping.pingecho host, 1.0
  end

  # run this in the context of the including class:
  def self.included(base_class)
    base_class.class_eval do
      has_many :live_streams
 
      validates_uniqueness_of :host
      validates_presence_of   :name

      named_scope :ordered_by_host, {:order => "host"}
    end
  end
end

There!  The errors are gone, and all of our general network device code is in one place.  Now, our code is easier to maintain, is less susceptible to bugs, and we'll probably even save our clients/employers some money in the long run.

Tuesday, July 28, 2009

Rails/Postgres Setup Gotchas - Ubuntu 9.04

I recently switched to Ubuntu 9.04 after using OpenSUSE- and Fedora-Based development environments for several years, and it's been great for both Rails development and general use. The defaults are well-chosen, hardware integration is seamless, and in general, the user experience is the best I've seen of any Linux distro. Still, the default Ubuntu install is missing many important development packages; I had to take a few unexpected steps to get a simple, Postgres-backed Rails project running under Ruby 1.8. Hopefully, documenting these steps will save time for other developers.


First, install basic ruby and rubygems packages:

$ sudo apt-get install ruby ruby-dev rubygems

If your app needs to make requests over SSL, i
nstall Ruby OpenSSL bindings:
$ sudo apt-get install libopenssl-ruby

SET UP POSTGRES AND DATABASES:
Install basic postgres packages. Note that some applications won't require postgresql-contrib:
$ sudo apt-get install postgresql postgresql-8.3 postgresql-8.3-plr
postgresql-client-8.3 postgresql-client-common postgresql-common
postgresql-contrib postgresql-contrib-8.3 postgresql-server-dev-8.3

Install the postgres gem (tested w/ version 0.7.9.2008.01.28)
$ sudo gem install postgres

Initialize postgres. As your system's postgres user:
$ initdb -D /var/lib/pgsql/data
$ pg_ctl -D /var/lib/pgsql/data -l logfile start

Make sure postgres starts on boot. In Ubuntu, this should be done automatically for you, but just to be sure:
$ sudo update-rc.d postgresql-8.3 defaults
# System startup links for /etc/init.d/postgresql-8.3 already exist

As the postgres user, create a user for psql; answering no to all questions. This will probably be the user referenced in your database.yml config file.
$ createuser dbuser

In order to give the user privilages to run DROP DATABASE for commands like
rake:test, you may have to do the following in psql:
ALTER USER dbuser CREATEUSER;

Monday, May 11, 2009

Ruby-gcal is Released!

I just released my open-source Google Calendar library, ruby-gcal, on GitHub!  Check it out here.

There are more features in the works, but for now, it allows you to add, update and delete multiple events with few HTTP requests using Google's batch processing API.  When I have some more free time, I plan on releasing an "acts_as_google_calendar_event" sort of Rails plugin, so model objects corresponding to Google Calendar events can be saved to a database and synced with a GCal account.