Hackathon 2012Casual dress code

What Does Culture Have To Do With It?

Jordi Diaz

More Than We Think

Is culture just a last name, family tradition, or second language? Or can it be more? Why and what should an intern learn about culture?

As an Intern for YP, I have come to learn that culture is not just about where we come from, but also where we would like to go. Before starting at YP, I had not given much thought to the importance of the culture a company fosters. Or realized the impact it has on the quality of not only its products but also on the quality of the effort that goes into them. Which qualities are important to your work?

Culture Points

Firstly, the big one: Communication. It is at the top of the list, of important cultural qualities, because this is what will allow you to grow. Being able to talk to your superior about where you would like to go with a project, or department or even career path is an irreplaceable quality. Being heard and acknowledged keeps us motivated and happy. This something that YP emphasizes and strives at. Everyone is open to talk about whatever is on your mind.

Secondly, Atmosphere. What kind of atmosphere are you most productive in? Knowing what work environment you are comfortable in and lets you explore creatively is an important factor to the quality of your work. Being an Intern for YP and seeing first hand has allowed me to understand that how we work is part of where we work. A relaxed working atmosphere where people wear shorts and sandals may help you be productive but may not be ideal for everyone.

Lastly, Drive. No I do not mean the getaway driver flick with Ryan Gosling. I mean motivation and ambition. I use to believe that as long as I knew how to code that I could work on anything sufficiently well. Unfortunately, having seen the experience friends have had at their internships and comparing them to mine I can see a pattern. If you are not driven to complete your project and excited about its functionality, you may not have the gusto to see it through with out burning out.

So, before you turn in that internship application make sure to check not just the pay, or the project but whether or not the existing employees like working there through GlassDoor or similar services. If it all seems to jive with who you are and they look like the employees below go ahead and click submit.

YP PDS Team image

What Does An Internship Give You?

Joe

As a YP Intern, I'm working hard. They've given me a significant amount to do and I'm having a blast doing it. But why am I doing the work? Why am I doing this internship and what am I getting out of it?

First, the obvious one: you do it for experience. But not for the experience of coding using a specific language or framework. If you've coded before, you can learn a new language or framework with a few days of immersion. Rather, the job teaches you about everything else - how to talk to and coordinate with your coworkers, how to manage upwards, and the best way to get to work in the morning. You learn more about yourself and what you want to do for a living. Sometimes you find out that you belong in that line of work and sometimes you learn that you'd rather be anywhere else, doing anything else. Both are ok - that's what internships are for.

Manage Your Career

An internship also teaches you how to manage your career. It is especially helpful if it is arranged for you to hear from Bill Theisinger, the VP of Platform Data Services here at YP. You'll hear him say things like "always counter" and "take risks" that you may have heard before, but never resonated with you quite the same way. You understand that when you're young, you have the opportunity to take risks that you'll never have again. If you're 22 and you take a big risk and fail, you pick yourself back up, live somewhere cheap and sketchy for a while, and find another path. If you're 43 and you fail, your family is affected. You have others to think about. So take risks early.

Another thing you learn from Bill is that if you're not getting what you deserve, it's your own fault. It's your responsibility to get out there and find a place that will give you what you deserve.

So remember, do internships. Be active - do a presentation or two! Take some risks. If you succeed, you get to be in charge.

“Interns

What Do The Users Want?

Kwun

We’re thinking about revamping a part of the YP.com site so I was tasked to do some competitive analysis. So what does that entail? Not only was I just looking at various YP competitors and see how they implemented their design, but to also look at totally unrelated sites to see what worked for a totally different product. Looking at the strategies of different websites can give great insight into what really works especially when all these websites online are trying to sell you something, be it an experience, service, or product, we’re all here to please our customers.

So I find all these great things from each site and Frankenstein them together to make the perfect component for YP right? Nope. What if I put all these great things together and it turned out to be a monstrosity? Something a user would look at ask themselves “why is there so much crap here?” So not only did I look at what sites did well at, but also what they didn’t do so well at and made sure I wouldn’t make the same design flaws that they did.

So that must be it right? I know the pros and cons of each design so now I must have the perfect formula! Nope. Perfect formula for who? Who am I selling this perfect formula to? I need to know my target audience and more importantly, what am I looking to achieve with my audience with this revamp? If you’ve never thought about this then it’s like trying to sell the perfect oil change that never has to be changed again to someone that doesn’t own a car. They don’t want it and you’re just wasting your time and resources.

As I aforementioned in my last post, the most important element a business needs to do is to understand their customers. What do they want? What do they expect? What can YP do to give them the most value possible? Through extensive research and with the help of one of the papers one of my UCLA Anderson professors co-authored, I distilled down what the user wanted and I'm determined to give it to them.

With the help of a UI designer, we created a mockup of what I envision the users seeing after the revamp. Looking at it through their eyes, what does each part inform me or ask me to do? Each element of the page had a reason behind it and each of them had a certain call to action for the user. I really liked how the mockup turned out and the feel it gave me when I looked at it and I hope that’s how the users will feel too when they look at it.

This was just a competitive analysis and a mockup, who knows if it will make it all the way through. I’m still in the process of deciding what my big project for my internship may be and this could be it.

On a side note, I’ve been hearing some of my friends saying that they’ve been hearing various YP ads on the radio in LA. I don’t listen to the local radio so I have no idea but I did run into my first YP bus stop ad on the weekend.

(Unintentional selfie from the reflection) “YP_busstop_ad”

The Freedom to Innovate

Nathan Cunningham

Alternate Flag

Freedom. Independence. Liberation.

It's what Americans celebrate tomorrow.

Consider one of the fruits of freedom the world over: The opportunity to make a living, support families, and build careers in liberated companies where we can innovate and produce things that help people.

In Isaac Getz's TEDx talk: "Liberate your company!" he talks compellingly about:

  • the need for companies to have engaged employees in order to boost innovation
  • the fact that in every company there are a combination of engaged employees (the roosters), disengaged employees (the tired dogs), and actively disengaged employees (the foxes)

He asserts that to liberate employees and enable greater engagement and thus innovation, leaders (both top down and leaders w/out title) need to create an environment for:

  • Intrinsic Equality
  • Personal Development
  • Self-Direction

YP is a place that offers this! It's an exciting time to work here. And this sounds a lot like what liberated and free societies offer their citizens. We are a privileged bunch, don't you agree?

Happy Independence Day!

The Story of Aaron Swartz

Oren

pic

Aaron Swartz was a programmer, writer, political and internet hacktivist. He co-founded Reddit, was involved in creating the RSS protocol and lead the fight against SOPA (Stop Online Piracy Act).

This documentary follows the events that led Aaron to take his own life at the age of 26. It aired at Sundance Film Festival and is free to download or stream here.


"it’s not enough to just live in the world as it is, to just kind of take what you’re given and follow the things that adults told you to do and that your parents told you to do and that society tells you to do. I think you should always be questioning...Once I realized that there were real, serious problems, fundamental problems that I could do something to address, I didn’t see a way to forget that" - Aaron, 1986 - 2013

Back in the workforce again...as an intern

Kwun Choy

So this is what it feels like to be working for a paycheck after taking a year off work to go back to school. Let's rewind a little bit first. After working 4 years designing computer chips after graduating from an Electrical Engineering undergrad, I decided to get my MBA at UCLA Anderson so I could have a bigger impact on a tech organization, to be able to better understand the business, the market, and most importantly, the customers. I want to create the most value for the customers while maintaining a healthy business. That's why I'm at YP.

I'm interning as a Product Manager at YP in the Consumer Products team for only 1.5 weeks now and I've learned more than I could imagine.

"I also have researchers behind the mirror observing our conversation"

Yesterday after going through treacherous LA traffic at 4PM, I arrived at a consumer testing center in Beverly Hills where we were holding focus group research. Have you seen those TV shows where they are interrogating criminals where the only light source was a table light shining into their eyes and the FBI is watching the whole process through a one-way mirror waiting for the perfect moment to pounce in? It was kind of like that but there was no criminal, room was well lit, refreshments served to participants, and no one was part of the FBI. No physical altercation was involved either.

It was interesting to hear all these strangers talk about their individual experience using YP. Some of them really liked a feature, some of them didn't. Some wanted YP to add some extra services YP should provide, some wanted more simplicity. Some of the items they pointed out we already knew about, some of them said pretty outrageous suggestions (YP can get you to the moon though). All in all I thought it was very fascinating and enjoyed my time learning from them.


A Scalding Tutorial

Ying Yang

Drawing As a data focused person, I use Pig/Hive + java UDF to process big data, and also write java map reduce jobs daily. But I am wondering if there is a single language that can do all jobs. The answer is yes. Scalding is a scala DSL which allows you to specify a data processing flow. You can use its type safe api like map, group, reduce and join functions to do whatever you can do in pig and hive. And also, you can construct more concise and readable UDF since scala is a functional programming language. Moreover, the scalding map reduce job is much more shorter than its equivalent in java. With all advantages of scalding, let's start our tutorial of how to use it to build our data pipeline.

1. Setup sbt

Before we start, lets set up sbt first. Sbt is a build tool for java and scala. If you are familiar with Maven, sbt is similar. This link setup sbt introduces how to set up sbt with every detail.

2. Build a simple scalding project

Now, we will build a simple scalding project to find out how many duplicate search terms are there in our input text file.

2.0. Project layout

By typing the following command, we can create the structure for our example project.

command line:
$mkdir example
$cd example
$mkdir project
$mkdir src
$mkdir -p src/main/scala/com/yp/hadoop/scalding
$mkdir -p src/test
$mkdir data

project layout:
/example
   |-data
   |-project
   |-src
   |---main
   |-----scala
   |-------com
   |---------yp
   |-----------hadoop
   |-------------scalding
   |---test

2.1. Set up project

After we create all the folders, we need to configure our project. Let's go to the project folder and create the following files:

/project
   |-build.properties
   |-BuildSettings.scala
   |-Dependencies.scala
   |-plugins.sbt
   |-exampleBuild.scala

And add content to each file:

build.properties

sbt.version=0.12.3

BuildSettings.scala

import sbt._
import Keys._

object BuildSettings {

  // Basic settings for our app
  lazy val basicSettings = Seq[Setting[_]](
    organization  := "yellowpages.com",
    version       := "0.0.4",
    description   := "example",
    scalaVersion  := "2.9.2",
    scalacOptions := Seq("-deprecation", "-encoding", "utf8"),
    resolvers     ++= Dependencies.resolutionRepos
  )

  // sbt-assembly settings for building a fat jar
  import sbtassembly.Plugin._
  import AssemblyKeys._
  lazy val sbtAssemblySettings = assemblySettings ++ Seq(

    // Slightly cleaner jar name
    jarName in assembly <<= (name, version) { (name, version) => name + "-" + version + ".jar" },

    // Drop these jars
    excludedJars in assembly <<= (fullClasspath in assembly) map { cp =>
      val excludes = Set(
        "jsp-api-2.1-6.1.14.jar",
        "jsp-2.1-6.1.14.jar",
        "jasper-compiler-5.5.12.jar",
        "minlog-1.2.jar", 
        "janino-2.5.16.jar", 
        "commons-beanutils-core-1.8.0.jar", 
        "commons-beanutils-1.7.0.jar",     
        "hadoop-core-0.20.2.jar", 
        "hadoop-tools-0.20.2.jar"
      ) 
      cp filter { jar => excludes(jar.data.getName) }
    },

    mergeStrategy in assembly <<= (mergeStrategy in assembly) {
      (old) => {
        case "project.clj" => MergeStrategy.discard // Leiningen build files
        case x => old(x)
      }
    }
  )

  lazy val buildSettings = basicSettings ++ sbtAssemblySettings
}

Dependencies.scala

import sbt._

object Dependencies {
  val resolutionRepos = Seq(
    ScalaToolsSnapshots,
    "Concurrent Maven Repo" at "http://conjars.org/repo" // For Scalding, Cascading etc
  )

  object V {
    val scalding  = "0.8.5"
    val hadoop    = "0.20.2"
    val specs2    = "1.12.3" // -> "1.13" when we bump to Scala 2.10.0
    // Add versions for your additional libraries here...
  }

  object Libraries {
    val scaldingCore = "com.twitter"                %%  "scalding-core"       % V.scalding
    val hadoopCore   = "org.apache.hadoop"          % "hadoop-core"           % V.hadoop       % "provided"
    // Add additional libraries from mvnrepository.com (SBT syntax) here...
    val evoInflector = "org.atteo"  % "evo-inflector" % "1.0.1"
    // Scala (test only)
    val specs2       = "org.specs2"                 %% "specs2"               % V.specs2       % "test"
    val morphaStemmer   = "edu.washington.cs.knowitall" % "morpha-stemmer" % "1.0.5"
  }
}

plugins.sbt

resolvers += Resolver.url("plugins-artifactory", url("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(Resolver.ivyStylePatterns)

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.5")

exampleBuild.scala

import sbt._
import Keys._

object exampleBuild extends Build {

  import Dependencies._
  import BuildSettings._

  // Configure prompt to show current project
  override lazy val settings = super.settings :+ {
    shellPrompt := { s => Project.extract(s).currentProject.id + " > " }
  }

  // Define our project, with basic project information and library dependencies
  lazy val project = Project("example", file("."))
    .settings(buildSettings: _*)
    .settings(
      libraryDependencies ++= Seq(
        Libraries.scaldingCore,
        Libraries.hadoopCore,
        Libraries.specs2,
        // Add your additional libraries here (comma-separated)...
        Libraries.evoInflector,
        Libraries.morphaStemmer
      )
    )
}

2.2. Input file

Now lets create some tab delimited input file in data folder called in.txt

restaurant | los angeles, CA | 4(clicks)

restaurants | los angeles, CA | 5(clicks)

24 hours | new york city, NY | 3(clicks)

24 hour | new york city, NY | 5(clicks)

2.3. Scalding classes

Let's create classes for scalding job

src/main/scala/com/yp/hadoop/scalding
   |-Deplural.scala
   |-JobRunner.scala

Add add the following code to each class

Deplural.scala

import com.twitter.scalding._
import org.atteo.evo.inflector.English
import edu.washington.cs.knowitall.morpha.MorphaStemmer

class DePlural(args : Args) extends Job(args) {
  val r = """\t|\001"""
  TextLine( args("input") )
    .map('line -> ('word,'query,'geo,'clicks, 'qc)) { line : String => (deplural(line.split(r)(0)),line.split(r)(0), line.split(r)(1), line.split(r)(2), List(line.split(r)(0), line.split(r)(2)).mkString(":")) }
    .groupBy('word, 'geo) {_.size('dup_count).sortBy('clicks).reverse.mkString('qc,",")}
    .filter('dup_count) {dup_count : Int => dup_count>1}
    .write( Tsv( args("output") ) )

  // Split a piece of text into individual words and use MorphaStemmer to stem
  def deplural(text : String) : String = {
    // Lowercase each word and deplural.
    val words = text.toLowerCase.split("\\s+")
    (for (w <- words) yield MorphaStemmer.stem(w)).mkString(" ")
  }
}

JobRunner.scala

package com.yp.hadoop.scalding

// Hadoop
import org.apache.hadoop

// Scalding
import com.twitter.scalding.Tool

object JobRunner {
  def main(args : Array[String]) {
    hadoop.util.ToolRunner.run(new hadoop.conf.Configuration, new Tool, args);
  }
}

3. How to run

We can test run our code either locally or on hdfs. Suppose you already set up your hadoop.

//run locally
hadoop jar target/example-0.0.4.jar com.yp.hadoop.scalding.DePlural \
--local \
--input data/in.txt \
--output data/out.txt


// run on hadoop
hadoop jar scalding-example-project-0.0.4.jar com.snowplowanalytics.hadoop.scalding.DePlural \
--hdfs \
--input /yourhdfspath/in \
--output /yourhdfs/out

We can get the following output: Our output should look like:

out.txt

restaurant | los angeles | [restaurant:4, restaurants:5]

24 hour | new york | [24 hours:3, 24 hour:5]

4. Closing

Scalding is good for complex data pipelines since you can integrate your customized functions wherever you want. Hope you enjoy the scalding tutorial!

What a 16th Century Samurai Teaches Us About VOICE - Part One

Jeff Leeson

This is the first post in a series on the VOICE principles and the philosophy of Miyamoto Musashi as written in The Book of Five Rings. The translation of The Book of Five Rings used here was sourced from WikiQuote.

YP and its team members practice the VOICE principles (Velocity, Ownership, Innovation, Collaboration, and Execution), and we are all annually rated by our embodiment of those principles. By following these principles, you will be a more effective leader, employee, and entrepreneur.

The Book of Five Rings, written by Miyamoto Musashi, describes a philosophy called “The Way.” Miyamoto Musashi was a renowned Japanese samurai who lived in the 16th century and The Way is a philosophy of sword fighting which can be applied across any discipline. Musashi’s writings are still studied today.

This series explains how the sword fighting principles of The Way can be generalized to each VOICE principle, leading you to becoming more productive.

Velocity

Velocity is about consistently moving forward, regardless of obstacles, but always with a purpose and intentional direction. It keeps us nimble as individuals and as groups of varying sizes, and allows us to ebb and flow as necessary to not just survive, but to win.

Here is what Musashi says about Velocity:

It is difficult for large numbers of men to change position, so their movements can be easily predicted. An individual can easily change his mind, so his movements are difficult to predict. You must appreciate this. The essence of this book is that you must train day and night in order to make quick decisions.

As individuals, teams, and as a company as a whole, we must practice decisiveness in every judgment. We choose quickly, and commit completely.

In strategy your spiritual bearing must not be any different from normal. Both in fighting and in everyday life you should be determined though calm. Meet the situation without tenseness yet not recklessly, your spirit settled yet unbiased. Even when your spirit is calm do not let your body relax, and when your body is relaxed do not let your spirit slacken.

Perseverance of awareness at all times is necessary. As part of Velocity and moving forward, we need to be constantly aware of where we are, where our competitors are, and where our customers are. This awareness allows us to rethink whether we’re moving in the correct direction and making the right decisions and whether any changes are necessary to maintain our velocity.

Be neither insufficiently spirited nor over spirited. An elevated spirit is weak and a low spirit is weak. Do not let the enemy see your spirit.

Our outward appearance, as a company, as a team, as individuals, should remain vigilant and consistent at all times. We should never appear as though we’re reactionary, too slow, too fast, neither excited nor tranquil; we move always at an appropriate pace.

In all forms of strategy, it is necessary to maintain the combat stance in everyday life and to make your everyday stance your combat stance. You must research this well.

Our velocity is demonstrated in all activities. In the code of our products, in our customer service and our community service, and in our team, family, and cultural commitments, our velocity never falters and is always steady.

“There are many enemies” applies when you are fighting one against many. Draw both sword and companion sword and assume a wide-stretched left and right attitude. The spirit is to chase the enemies around from side to side, even though they come from all four directions. Observe their attacking order, and go to meet first those who attack first. Sweep your eyes around broadly, carefully examining the attacking order, and cut left and right alternately with your swords. Waiting is bad. Always quickly re-assume your attitudes to both sides, cut the enemies down as they advance, crushing them in the direction from which they attack.

YP is challenged by many competitors, each posing their own unique test. We don’t fight, or stay ahead, of each one, but instead work them all simultaneously. We must maintain our velocity, sweeping across those who “attack” first with their own products and innovations. We don’t wait for others to innovate, we act first, with deliberate movement and velocity, seizing every opportunity to revolutionize a product, create a new one, sell that product, and please that customer in both the performance of the product as well as our customer service.

Some men use a shorter long sword with the intention of jumping in and stabbing the enemy at the unguarded moment when he flourishes his sword. This inclination is bad.

We don’t build a single product, waiting to find a customer for whom the product will fit. Nor does velocity mean we wait for the “right time” to propose a new technology, enter a market, release a product, or make a sale. We practice velocity by continually improving, never waiting for an opportunity, but creating opportunities with our forward movement.

Really skillful people never get out of time, and are always deliberate, and never appear busy. From this example, the principle can be seen.

Here Musashi summarizes velocity perfectly. As a company and as individuals with velocity, our actions are performed with purpose, thought, and confidence. There is no ebb and flow, only consistency of performance, wisely and decisively wielding time and resources.

Conclusion

Now that you’ve read how to achieve velocity using The Way, you need to start acting on these principles. Begin by applying what it means to have velocity (decisiveness, awareness, persistency, confidence, and consistency) to your daily work. Tell yourself at the beginning of each day that you will embody velocity in all that you do, and be a model to others in your actions.

Next in the series, we’ll read what Miyamoto Musashi says about ownership.

Wrangling Ruby Versions, 2014 Edition

Chris Fincher

In an ideal world, we wouldn't need software to switch Ruby versions. In an ideal world, we wouldn't need Ruby versions at all. Matz would simply have been struck by divine inspiration and shared his vision of the perfect programming language with the world, including every feature that would be added over time to Ruby in our flawed universe (fully optimized, of course). Alas, we do not live in a perfect world, and that's simply not how languages are designed (despite what some Scala fans will tell you). It's not all bad. Matz is famously nice in our world. If Ruby would have happened the other way, he might not have been as nice. The fame certainly would have gone to my head.

In any event, we live in a universe with versions, and working on more than one Ruby app frequently means switching back and forth between them numerous times a day. The good news is that this doesn't take much thought nowadays, thanks to Ruby version management tools. Honestly, if you're the target audience for this post, you probably already know what these do, but just in case, these are pieces of software that help you maintain separate Ruby installations for each version of Ruby that you need on your system and switch between them at will. That way, you can run code for your super-disruptive, VC-ready social something-or-other on the newest, fastest Ruby and code that's not worth the trouble of updating on whatever Ruby it was written for. Four tools, all free and open-source, dominate the landscape: RVM, rbenv, chruby, and ry. (Others have been historically popular but have since been deprecated.) I've seen posts that compare RVM to rbenv or rbenv to chruby, but nothing covering the whole gamut. I decided I would try to fill that gap, so I've put together a rundown of what the state of Ruby version management is today, and which tool is the best for you.

Ultimately, what we want these programs to do is manipulate your system PATH variable, so that when you type "ruby" and hit enter, your system finds the right Ruby. There are many ways to do this, but the aforementioned tools use these methods:

  • RVM and chruby change your PATH every time you switch Rubies so that your chosen Ruby is given priority.
  • rbenv adds a directory of "shims" to your PATH. The shims are small executables with the same names as Ruby executables, i.e., ruby, bundle, rack, etc... This causes a shim to be run when you try to run the corresponding Ruby executable. The shim invokes rbenv, which then figures out the correct Ruby to run.
  • ry adds a location to your path that is symlinked to the Ruby of your choice. When you switch Rubies, ry updates the symlink.

I had originally planned to go through these one-by-one, giving the pros and cons, but it was too easy to get lost in edge cases and minor details that most users don't need to know. So here's the approach I'm recommending instead: write down the four version managers I've introduced, and read through the headings below. If one applies to you, stop and read. Otherwise, you can skip that section. At the end of the article, you'll probably have crossed a few off, and you'll know what will work for you.

I'm joining a team that already has a preferred version manager.

Use theirs. You don't want to be the person that can't change your config with everyone else because you decided to be different. It would be a different story if one of these tools were clearly less reliable than the others, but they all do an excellent job.

I'm using RubyMine.

Cross off chruby and ry. RubyMine is planning to add chruby support, but it hasn't happened yet.

I want my machine to automatically use the right Ruby for the project I'm working on.

Cross off ry. It doesn't support automatic version switching. rbenv inherently supports this. Since every invocation of ruby invokes rbenv, there's nothing to update when you switch Rubies. RVM and chruby support this by updating when you cd into a project directory.

...and my team has .rvmrc or .ruby-version files in its projects.

.rvmrc is only used by RVM. Use RVM if you want to use the settings within it. .ruby-version is read by RVM, rbenv, and chruby, but RVM is more generous with matching than the others. rbenv and chruby expect the file to correspond exactly with the name of a version of Ruby that you have, e.g. 1.9.2-p320 or ree-1.8.7-2011.12. RVM will accept 1.9.2 and select whatever patch level of Ruby 1.9.2 you have installed. If you want to accept .ruby-version files that contain versions without patch levels, use RVM.

...and I never, ever want to interact with my version manager.

The downside to rbenv's shim method is that you use the same set of shims for every project. If the executables that you can run change, the shims can become out-of-date. You have to run rbenv rehash when this happens. If this is a dealbreaker for you, either avoid rbenv or install the rbenv-gem-rehash plugin, which runs rehash every time you install a gem.

I want to keep the gems I use for each project separate and Bundler does not meet my needs.

RVM includes a feature called "gemsets" that allows you to run each project in its own sandbox of gems. rbenv also supports this through a plugin called rbenv-gemset.

I want a GUI.

RVM has an official OS X GUI called JewelryBox.

I need to run Ruby 1.8.7 or Ruby Enterprise Edition.

chruby and rbenv do not include Ruby installation support by design. These are commonly paired with either ruby-build, ruby-install, or RVM (which provides an executable called mrvm that exclusively installs Rubies) to install the Rubies to be managed. ruby-install does not support Ruby 1.8.7, so be sure to pair rbenv or chruby with one of the others if this is a need of yours.

It behooves me to mention that Ruby 1.8.7 is end-of-life, and you probably still will have to do funny things to get it to install on the newest OS X or Linux. If at all possible, it might be more efficient to move the project you're using it for to 1.9.3, at least.

Overriding cd makes me nervous.

RVM's auto-switching is enabled by overriding cd in the terminal. If you don't like this, either disable automatic version detection or don't use RVM. If you like the installation capabilities of RVM but would rather use chruby or rbenv for automatic selection, RVM provides a tool called mrvm for just that purpose.

Do one thing, and do it well.

chruby only switches your Ruby version. It does not install Ruby. It does not have plugins. Its creator sees feature creep as an infection. If these statements resonate with you, consider chruby. It pairs nicely with ruby-install, which installs versions of Ruby and does nothing else.

I want to be able to read the code I run.

chruby and ry are both set up very simply and can be read with relative ease. chruby prides itself on being only 90-ish lines.

I want to be able to use Rubies installed in scattered folders.

Only chruby will let you specify multiple arbitrary locations for your Ruby installations. RVM, rbenv, and ry all expect for your ruby installations to be contained within one folder, though they do let you specify which folder that is. If you can't keep all of your Ruby installation directories within one parent directory, you'll need to either use chruby or add symlinks to make them appear in your RVM/rbenv/ry home directory.

So which one should I use?

Let's see how your list is looking. If there's only one that hasn't been crossed off, congratulations. Meet your new ruby version management tool. If not, well, we just have to accept that there is a variety of free-as-in-freedom tools that perform this job admirably. Unfortunately. I say it's unfortunate because I know it's easy to agonize over what tool is best for the task at hand when there's no clear answer and to worry that you'll pick incorrectly and become entrenched in a workflow that you find out is sub-optimal after it's far too late to change. It's vim vs. emacs all over again. Perhaps the First-Worldliest of the First-World Problems. In this case, if the use cases I went over haven't made one of them the clear choice, just pick one from the ones you have left. Roll a die. The conventional wisdom is that chruby is a good choice if you fancy yourself a hacker or power user, RVM is nice if you just want things to work without worrying about technical details, and rbenv is somewhere in the middle. Perhaps that pushes you in one direction, but even if it doesn't, don't let it bother you and move on with something. Odds are, you won't regret it.

Flappy Bird and YP.com

Oren

We just had an awesome 2 days Hackathon at YP where we cranked some cool little projects. I was part of 'Team Flappy'. Our hack was Flappy Bird integration with YP.com. If it ever hits production you'll have to look for it!