Updating the gallery for our Hobo 2.0 release

Posted 4 months back at The Hobo Blog

I made some substantial updates to http://cookbook.hobocentral.net yesterday.

The plan is to replace the main hobocentral.net site with the cookbook site. To that end, I’ve copied the home, about, books and gallery pages from hobocentral.net into appropriate places in the cookbook, and updated them as appropriate.

The gallery page is quite old. I know there are a lot more Hobo sites out there in the wild; I’d ask everybody to send me links. Even better would be to add the sites yourself. Like almost every page on the cookbook, there’s now an edit link on the bottom of the gallery.

You may notice that if you click on any edit link, the cookbook asks for authorization to access your public GitHub profile. That’s a hack I added only to ensure that you’re logged into GitHub. Otherwise the edit links would 404 if you aren’t logged into GitHub.

Comments, feedback and assistance with the cookbook site would be greatly appreciated. This is going to be the public face of Hobo for 2.0.

Updating the gallery for our Hobo 2.0 release

Posted 4 months back at The Hobo Blog

I made some substantial updates to http://cookbook.hobocentral.net yesterday.

The plan is to replace the main hobocentral.net site with the cookbook site. To that end, I’ve copied the home, about, books and gallery pages from hobocentral.net into appropriate places in the cookbook, and updated them as appropriate.

The gallery page is quite old. I know there are a lot more Hobo sites out there in the wild; I’d ask everybody to send me links. Even better would be to add the sites yourself. Like almost every page on the cookbook, there’s now an edit link on the bottom of the gallery.

You may notice that if you click on any edit link, the cookbook asks for authorization to access your public GitHub profile. That’s a hack I added only to ensure that you’re logged into GitHub. Otherwise the edit links would 404 if you aren’t logged into GitHub.

Comments, feedback and assistance with the cookbook site would be greatly appreciated. This is going to be the public face of Hobo for 2.0.

Updating the gallery for our Hobo 2.0 release

Posted 4 months back at The Hobo Blog

I made some substantial updates to http://cookbook.hobocentral.net yesterday.

The plan is to replace the main hobocentral.net site with the cookbook site. To that end, I’ve copied the home, about, books and gallery pages from hobocentral.net into appropriate places in the cookbook, and updated them as appropriate.

The gallery page is quite old. I know there are a lot more Hobo sites out there in the wild; I’d ask everybody to send me links. Even better would be to add the sites yourself. Like almost every page on the cookbook, there’s now an edit link on the bottom of the gallery.

You may notice that if you click on any edit link, the cookbook asks for authorization to access your public GitHub profile. That’s a hack I added only to ensure that you’re logged into GitHub. Otherwise the edit links would 404 if you aren’t logged into GitHub.

Comments, feedback and assistance with the cookbook site would be greatly appreciated. This is going to be the public face of Hobo for 2.0.

Our Intro to Ruby on Rails workshop is now available online

Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

I’m very pleased announce that our popular Intro to Ruby on Rails workshop is now available to take as a month-long online version.

The online workshop will run from February 4th to March 1st. After that, you get ongoing support from the thoughtbot team for any Ruby on Rails questions you have.

Our online workshops have been going very well, and in this latest round we’ve switched from text-based Campfire chat for office hours to full audio and video in Google Hangouts.

Register today for the upcoming online session of Intro to Ruby on Rails.

An Instrumented Library in ~30 Lines

Posted 4 months back at RailsTips.org - Home

The Full ~30 Lines

For the first time ever, I am going to lead with the end of the story. Here is the full ~30 lines that I will break down in detail during the rest of this post.

require 'forwardable'

module Foo
  module Instrumenters
    class Noop
      def self.instrument(name, payload = {})
        yield payload if block_given?
      end
    end
  end

  class Client
    extend Forwardable

    def_delegator :@instrumenter, :instrument

    def initialize(options = {})
      # some other setup for the client ...
      @instrumenter = options[:instrumenter] || Instrumenters::Noop
    end

    def execute(args = {})
      instrument('client_execute.foo', args: args) { |payload|
        result = # do some work...
        payload[:result] = result
        result
      }
    end
  end
end

client = Foo::Client.new({
  instrumenter: ActiveSupport::Notifications,
})

client.execute(...) # I AM INSTRUMENTED!!!

The Dark Side

A while back, statsd grabbed a hold of the universe. It swept in like an elf on a unicorn and we all started keeping track of stuff that previously was a pain to keep track of.

Like any wave of awesomeness, it came with a dark side that was felt, but mostly overlooked. Dark side? Statsd? Graphite? You must be crazy! Nope, not me, definitely not crazy this one. Not. At. All.

What did we all start doing in order to inject our measuring? Yep, we started opening up classes in horrible ways and creating hooks into libraries that sometimes change rapidly. Many times, updating a library would cause a break in the stats reporting and require effort to update the hooks.

The Ideal

Now that the wild west is settling a bit, I think some have started to reflect on that wave of awesomeness and realized something.

I no longer want to inject my own instrumentation into your library. Instead, I want to tell your library where it should send the instrumentation.

The great thing is that ActiveSupport::Notifications is pretty spiffy in this regard. By simply allowing your library to talk to an “instrumenter” that responds to instrument with an event name, optional payload, and optional block, you can make all your library’s users really happy.

The great part is:

  1. You do not have to force your users to use active support. They simply need some kind of instrumenter that responds in similar fashion.
  2. They no longer have to monkey patch to get metrics.
  3. You can point them in the right direction as to what is valuable to instrument in your library, since really you know it best.

There are a few good examples of libraries (faraday, excon, etc.) doing this, but I haven’t seen a great post yet, so here is my attempt to point you in what I feel is the right direction.

The Interface

First, like I said above, we do not want to force requiring active support. Rather than require a library, it is always better to require an interface.

The interface that we will require is the one used by active support, but an adapter interface could be created for any instrumenter that we want to support. Here is what it looks like:

instrumenter.instrument(name, payload) { |payload|
  # do some code here that should be instrumented
  # we expect payload to be yielded so that additional 
  # payload entries can be included during the 
  # computation inside the block
}

Second, we have two options.

  1. Either have an instrumenter or not. If so, then call instrument on the instrumenter. If not, then do not call instrument.
  2. The option, which I prefer, is to have a default instrumenter that does nothing. Aptly, I call this the noop instrumenter.

The Implementation

Let’s pretend our library is named foo, therefore it will be namespaced with the module Foo. I typically namespace the instrumenters in a module as well. Knowing this, our noop instrumenter would look like this:

module Foo
  module Instrumenters
    class Noop
      def self.instrument(name, payload = {})
        yield payload if block_given?
      end
    end
  end
end

As you can see, all this instrumenter does is yield the payload if a block is given. As I mentioned before, we yield payload so that the computation inside the block can add entries to the payload, such as the result.

Now that we have a default instrumenter, how can we use it? Well, let’s imagine that we have a Client class in foo that is the main entry point for the gem.

module Foo
  class Client
    def initialize(options = {})
      # some other setup for the client ...
      @instrumenter = options[:instrumenter] || Instrumenters::Noop
    end
  end
end

This code simply allows people to pass in the instrumenter that they would like to use through the initialization options. Also, by default if no instrumenter is provided, we use are noop version that just yields the block and moves on.

Note: the use of || instead of #fetch is intentional. It prevents a nil instrumenter from being passed in. There are other ways around this, but I have found using the noop instrumenter in place of nil, better than complaining about nil.

Now that we have an :instrumenter option, someone can quite easily pass in the instrumenter that they would like to use.

client = Foo::Client.new({
  :instrumenter => ActiveSupport::Notifications,
})

Boom! Just like that we’ve allowed people to inject active support notifications, or whatever instrumenter they want into our library. Anyone else getting excited?

Once we have that, we can start instrumenting the valuable parts. Typically what I do is I setup delegation of the instrument to the instrumenter using ruby’s forwardable library:

require 'forwardable'

module Foo
  class Client
    extend Forwardable

    # forward instrument in this class to @instrumenter, for those unfamilier
    # with forwardable.
    def_delegator :@instrumenter, :instrument

    def initialize(options = {})
      # some other setup for the client ...
      @instrumenter = options[:instrumenter] || Instrumenters::Noop
    end
  end
end

Now we can use the instrument method directly anywhere in our client instance. For example, let’s say that client has a method named execute that we would like to instrument.

module Foo
  class Client
    def execute(args = {})
      instrument('client_execute.foo', args: args) { |payload|
        result = # do some work...
        payload[:result] = result
        result
      }
    end
  end
end

With just a tiny wrap of the instrument method, the users of our library can do a ridiculous amount of instrumentation. For one, note that we pass the args and the result along with the payload. This means our users can create a log subscriber and log each method call with timing, argument, and result information. Incredibly valuable!

They can also create a metrics subscriber that sends the timing information to instrumental, metriks, statsd, or whatever.

The Bonus

You can even provide log subscribers and metric subscribers in your library, which means instrumentation for your users is simply a require away. For example, here is the log subscriber I added to cassanity.

require 'securerandom'
require 'active_support/notifications'
require 'active_support/log_subscriber'

module Cassanity
  module Instrumentation
    class LogSubscriber < ::ActiveSupport::LogSubscriber
      def cql(event)
        return unless logger.debug?

        name = '%s (%.1fms)' % ["CQL Query", event.duration]

        # execute arguments are always an array where the first element is the
        # cql string and the rest are the bound variables.
        cql, *args = event.payload[:execute_arguments]
        arguments = args.map { |arg| arg.inspect }.join(', ')

        query = "#{cql}"
        query += " (#{arguments})" unless arguments.empty?

        debug "  #{color(name, CYAN, true)}  [ #{query} ]"
      end
    end
  end
end

Cassanity::Instrumentation::LogSubscriber.attach_to :cassanity

All the users of cassanity need to do to get logging of the CQL queries they are performing and their timing is require a file (and have activesupport in their gemfile):

require 'cassanity/instrumentation/log_subscriber'

And they get logging goodness like this in their terminal:

The Accuracy

But! BUT, you say. What about the tests? Well, my friend, I have that all wrapped up for you as well. Since it is so easy to pass through an instrumenter to our library, we should probably also have an in memory instrumenter that keeps track of the events instrumented, so you can test thoroughly, and ensure you don’t hose your users with incorrect instrumentation.

The previous sentence was quite a mouthful, so my next one will be short and sweet. For testing, I created an in-memory instrumenter that simply stores each instrumented event with name, payload, and the computed block result for later comparison. Check it:

module Foo
  module Instrumenters
    class Memory
      Event = Struct.new(:name, :payload, :result)

      attr_reader :events

      def initialize
        @events = []
      end

      def instrument(name, payload = {})
        result = if block_given?
          yield payload
        else
          nil
        end

        @events << Event.new(name, payload, result)

        result
      end
    end
  end
end

Now in your tests, you can do something like this when you want to check that your library is correctly instrumenting:

instrumenter = Foo::Instrumenters::Memory.new

client = Foo::Client.new({
  instrumenter: instrumenter,
})

client.execute(...)

payload = {... something .. }
event = instrumenter.events.last

assert_not_nil event
assert_equal 'client_execute.foo', event.name
assert_equal payload, event.payload

The End Result

With two instrumenters (noop, memory) and a belief in interfaces, we have created immense value.

Further Reading

Without any further ado, here are a few of the articles and decks that I read recently related to this.

Fin

Go forth and instrument all the things!

The new Rack socket hijacking API

Posted 4 months back at Phusion Corporate Blog

Yesterday saw the release of Rack 1.5.0, which adds a new feature to the Rack specification dubbed socket hijacking. This feature allows applications to take over the client socket and perform arbitrary operations on it, e.g. implementing WebSockets, streaming data to the client, etc.

Did Rack not support streaming? Actually yes it did, you can do it by returning a body object that outputs body chunks in the #each method, as explained in our past article Why Rails 4 Live Streaming is a Big Deal. But this API is a bit clunky. The socket hijacking API provides access to a Ruby IO object-like API.

Support for socket hijacking has been added to Phusion Passenger 4 yesterday. The upcoming Phusion Passenger 4 has been covered here, here and here. Phusion Passenger Enterprise customers can already test and enjoy a preview of this feature by downloading the “3.9.2 beta preview (4.0.0 beta 2)” file from the Customer Area.

The socket hijacking API was surprisingly easy to implement, but unfortunately poorly documented at this time. The application-level API is not immediately obvious, and the Rack specification documentation has not yet been updated to cover the hijacking API. In this article we’ll introduce the API and provide an example program.

What the socket hijacking API is not

Some of you may have heard of efforts to develop a “Rack 2.0″ specification which properly covers things such as streaming and evented servers. According to the hijacking API developer, this API is not an attempt towards Rack 2.0. It is a “good enough” solution that works within the confines of the Rack 1.x specification. Things may change in Rack 2.0, though at this time it’s unclear what the progress towards Rack 2.0 is.

It is also unclear whether the API is supposed to be final or not. While implementing this API and writing this article we’ve discovered some room for improvement. The suggestions (which you can find later in this article) have been submitted to the developers.

Overview of the API

The hijacking API provides two modes:

  1. A full hijacking API, which gives the application complete control over what goes over the socket. In this mode, the application server doesn’t send anything over the socket, and lets the application take care of it. This mode is useful if you want to implement arbitrary (even non-HTTP) protocols over the socket. This is subject to limitations: if your application is behind a web server or an HTTP load balancer then those components dictate which protocols you can implement.
  2. A partial hijacking API, which gives the application control over the socket after the application server has already sent out headers. This mode is mostly useful for streaming.

The hijacking API is accessible through the Rack env hash. You can check whether the application server supports the hijacking API by checking env['rack.hijack?'], which returns a boolean value.

Full hijacking

You can perform a full hijacking by calling env['rack.hijack'].call. You can access the hijacked socket object through env['rack.hijack_io']. Phusion Passenger’s implementation of env['rack.hijack'] returns the socket object, but it is unclear whether this is supposed to be standard behavior.

You are responsible for:

  • Outputting any HTTP headers, if applicable.
  • Closing the IO object when you no longer need it.

You should output the “Connection: close” header unless you plan on implementing HTTP keep-alive yourself.

Here’s am example of the full hijacking API in action:

# encoding: utf-8
require 'thread'

# Streams the response "Line 1" .. "Line 10", with
# 1 second sleep time between each line.
# 
# Non-Phusion Passenger users may have to turn off their
# web servers' buffering options for streaming to work.
# Phusion Passenger 4 users don't have to do anything, it
# works out-of-the-box thanks to our real-time response
# buffering feature.
app = lambda do |env|
  # Fully hijack the client socket.
  env['rack.hijack'].call
  io = env['rack.hijack_io']
  begin
    io.write("Status: 200\r\n")
    io.write("Connection: close\r\n")
    io.write("Content-Type: text/plain\r\n")
    io.write("\r\n")
    10.times do |i|
      io.write("Line #{i + 1}!\n")
      io.flush
      sleep 1
    end
  ensure
    io.close
  end
end

run app

Partial hijacking

You can perform a partial hijacking by assigning a lambda to the rack.hijack response header. This lambda will be called after the application server has sent out headers. The application server will ignore the body part of the Rack response, and will call the ‘rack.hijack’ lambda, passing it the client socket. You are responsible for closing the socket when it’s no longer needed.

It is unclear what the value of the Rack response body should be. Phusion Passenger’s implementation doesn’t care: you can return a two-array response, or a three-array response where where the body can be anything. If the ‘rack.hijack’ response header is set, the body will be completely ignored.

Example:

# encoding: utf-8
require 'thread'

# Streams the response "Line 1" .. "Line 10", with
# 1 second sleep time between each line.
# 
# Non-Phusion Passenger users may have to turn off their
# web servers' buffering options for streaming to work.
# Phusion Passenger 4 users don't have to do anything, it
# works out-of-the-box thanks to our real-time response
# buffering feature.
app = lambda do |env|
  response_headers = {}
  response_headers["Content-Type"] = "text/plain"
  response_headers["rack.hijack"] = lambda do |io|
    # This lambda will be called after the app server has outputted
    # headers. Here we can output body data at will.
    begin
      10.times do |i|
        io.write("Line #{i + 1}!\n")
        io.flush
        sleep 1
      end
    ensure
      io.close
    end
  end
  [200, response_headers, nil]
end

run app

Issues with the hijacking API

Here’s how we think the hijacking API can be improved.

  • env['rack.hijack?'] appears to be unnecessary. You can already check for hijacking support by checking env['rack.hijack'].
  • The partial hijacking API should not involve assigning a lambda to the response headers. As far as we can see, you can just return the lambda as the body. That would be a much more elegant solution.
  • The return value for env['rack.hijack'] should be well-defined.

Conclusion

The Rack hijacking API, while having some quirks in our opinion, gets the job done. We hope that the usage of the hijacking API has become more clear after reading this article. If you have any comments, questions, suggestions or corrections, please let us know.

We at Phusion are working feverishly at the upcoming Phusion Passenger 4 (covered here, here and here). Implementing the hijacking API so quickly is our way of showing you how dedicated we are. Together with Phusion Passenger Enterprise, we aim to deliver the most stable, performant and feature rich polyglot application server out there. If you’re interested in future updates, please subscribe to our newsletter. Until next time!



Ruby 1.9.3-p374

Posted 4 months back at The Ruby Show

In this episode, Jason and Peter talk about the latest Ruby release, developing iOS applications with Ruby, Kids Ruby, and the usual round up of interesting projects and posts.

Episode #338 - January 22nd, 2013

Posted 4 months back at Ruby5

Stretch your ElasticSearch, Profile your Ruby Threads, Sort your Nested Trees, Ruby in JavaScript, SoundCloud from Terminal while graphing your Hubtime.

Listen to this episode on Ruby5

This episode is sponsored by Top Ruby Jobs
If you're looking for a top Ruby job or for top Ruby talent, then you should check out Top Ruby Jobs. Top Ruby Jobs is a website dedicated to the best jobs available in the Ruby community.

Stretcher
Stretcher is a concise, fast ElasticSearch client designed to reflect the actual elastic search API as closely as possible.

NewRelic Ruby 3.5.5.38
The latest release of the New Relic Ruby agent includes Thread Profiling, Rails 4 Support and Audit Logging.

TheSortableTree
TheSortableTree gem provides a drag and drop GUI for working with nested sets in Rails.

RubyJS
RubyJS uses JavaScript to implement all methods from Ruby classes like Array, String, Numbers, Time and more.

SoundCloud2000
SoundCloud2000 is a command line interface written in Ruby for the SoundCloud API during the "Music Hack Day Stockholm"

Hubtime
Hubtime is a command line tool that uses Github’s API to print status and generate custom graphs based on your github activity.

Phusion Passenger 4 Technology Preview: Out-Of-Band Work

Posted 4 months back at Phusion Corporate Blog

Phusion Passenger is an Apache and Nginx module for deploying Ruby and Python web applications. It has a strong focus on ease of use, stability and performance. Phusion Passenger is built on top of tried-and-true, battle-hardened Unix technologies, yet at the same time introduces innovations not found in most traditional Unix servers. Since mid-2012, it aims to be the ultimate polyglot application server.

Development of the Phusion Passenger 4.x series is progressing steadily. The 4.x series is a huge improvement over the 3.x series: in the announcement for Phusion Passenger 4.0.0 beta 1, we introduced a myriad of changes such as support for multiple Ruby versions, Python WSGI support, multithreading (Enterprise only), improved zero-copy architecture, better error diagnostics and more. That was just the beginning, because soon after we announced JRuby and Rubinius support. Today we are announcing another cool feature.

Out-of-Band Work

The Out-of-Band Work feature allows one to perform arbitrary long-running work outside the request/response cycle without blocking HTTP clients. The primary use case is to run the garbage collector in between cycles so that your requests will finish faster because they will not be interrupted by the garbage collector.

Normally the garbage collector fires up as soon as the Ruby interpreter thinks it needs to, which possibly results in hundreds of milliseconds of latency. With the Out-of-Band Work feature, you can delay the garbage collector until the request has finished. While out-of-band work is running, Phusion Passenger will not route any requests to said process.

Cool properties of this feature:

  • If the process that triggered Out-Of-Band Work is the only process for that application, then Phusion Passenger will first spawn up a new process before performing the out-of-band work. When the out-of-band work has finished, the process will be eligible for idle timeout cleaning. Thus you can use this feature in any scenario, and Phusion Passenger will do the right thing for you.
  • It even works in multithreaded setups (an Enterprise-only feature). Normally the Ruby garbage collector will block all threads while doing work. So before performing the out-of-band work, Phusion Passenger will let all existing requests to the application process finish.
Before Out-Of-Band GC After Out-Of-Band GC Before and after applying out of band GC at AppFolio

This awesome feature has been contributed by AppFolio. They’ve been running it in production for a while now with quite some success. Average response time has gone down by 100 ms.

Compared to Unicorn’s OOBGC

Users who are familiar with Unicorn’s Out-of-Band GC (OOBGC) might notice the similarities. Our Out-of-Band Work feature (OOBW) is more general and more flexible:

  • Unicorn’s OOBGC requires a static number of single-threaded workers. OOBW is designed to be able to handle a dynamic number of workers that may even be multithreaded.
  • OOBW is designed to be able to perform arbitrary long-running work, including work that may block all threads. Unicorn’s OOBGC only works with garbage collection.

Using Out-Of-Band Work

Phusion Passenger 4.0 beta 2 provides a simple Rack middleware that you can use to enable out-of-band GC:

require 'phusion_passenger/rack/out_of_band_gc'
# Trigger out-of-band GC every 5 requests.
use PhusionPassenger::Rack::OutOfBandGc, 5

It also provides a simple API to perform Out-Of-Band Work. For example out-of-band GC may be implemented as follows without using the Rack middleware:

# Somewhere in a controller method:
# Tell Phusion Passenger we want to perform OOB work.
response.headers["X-Passenger-Request-OOB-Work"] = "true"

# Somewhere during application initialization:
PhusionPassenger.on_event(:oob_work) do
  # Phusion Passenger has told us that we're ready to perform OOB work.
  t0 = Time.now
  GC.start
  Rails.logger.info "Out-Of-Bound GC finished in #{Time.now - t0} sec"
end

Inside Out-Of-Band Work: a more general mechanism

The Out-Of-Band Work feature is actually built on top of an even more general mechanism: the enable/disable process feature. This is a new feature in Phusion Passenger 4 and is, for now, internal only. Internal Phusion Passenger code can mark a process as disabled, so that Phusion Passenger will no longer route requests to it. But the actual process is kept alive. Internal code can reenable the process later, making it eligible again for processing requests.

This feature is simple to use and simple to understand, but was tricky to implement. Phusion Passenger works in a heavily concurrent environment so it may not be able to disable a process immediately. The process might be handling requests, it might be restarting, another process might be spawning, etcetera. The entire API follows an asynchronous design. If the to-be-disabled process is the only process for that application, then Phusion Passenger will spawn another process. Disabling the original process will complete when the new process has been spawned, and the original process is done processing all its requests.

Once the enable/disable feature was in place, implementing Out-Of-Band Work was almost trivial. When an application wants to perform Out-Of-Band Work, it sends a signal to Phusion Passenger. We currently use the X-Passenger-OOB-Work header to do this, which is filtered out by Phusion Passenger and will never reach the client. Phusion Passenger will then try to disable the process. Once disabled, Phusion Passenger will send a signal to the application, telling it that it may proceed to perform out-of-band work. At this point the process is guaranteed not to be processing any requests, so it can freely do whatever it wants. Once the out-of-band work has finished, Phusion Passenger will reenable the process.

This simple mechanism opens the door to many other possibilities that are currently not implemented:

  • In the future we can add an admin command to access the API, so that the administrator can disable/enable processes. That way the administrator can temporarily isolate a process for debugging without disrupting production traffic.
  • Phusion Passenger Enterprise’s live IRB console feature can optionally disable the process before attaching itself, so that the administrator can debug the process without him being disrupted by traffic.

What Ruby can do to improve Out-of-Band Work

It would be great if the Ruby interpreter can provide some sort of API to find out when the garbage collector should be run. That way you can delegate all garbage collection work to the out-of-band phase. The current solution of running the garbage collector out-of-band every 5 requests works, but can be more optimal with help from Ruby.

Conclusion

Out-of-Band Work will become part of Phusion Passenger 4.0 beta 2, which will be released very soon. Please stay tuned for further announcements on Phusion Passenger 4. If you like, you can subscribe to our newsletters and we’ll keep you up to date.



Episode #32: There is an excited you in there

Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Episode #32: There is an excited you in there:

Ben Orenstein is joined this week by Daniel Jalkut, the developer of MarsEdit and other fine software. Ben and Daniel discuss the origin of Daniel’s twitter username, his history at Apple and his work there, and how it influences what he builds today. They also discuss the challenges of running your own company, and how Daniel’s priorities and rule systems help him get things done, how the success of MarsEdit takes up his attention at the exclusion of other ideas, and how he thinks about failure. Then then go on to talk about App Store versus direct sales, why Daniel still sells his software outside the app store as well as in it, and what the breakdown of sales are like there, as well as Daniel’s thoughts on App Store pricing and the benefits of being in the app store. Finally, Daniel tells us why he thinks git is like a PC and Mercurial is like a Mac, why he dislikes git, what he thinks makes a good podcast, how his podcast has changed, and much more.

distribute scripts as gist micro-gems

Posted 4 months back at Mike Mondragon

It's really easy to distribute scripts, not just gems, as gist micro-gems. Since rubygems and bundler can handle complicated dependencies the scripts you distribute can be more advanced than just ten or twenty lines.

I wrote a script to generate an OAuth key and secret for the Tumblr API and I made it available as a micro-gem. It is encapsulated in gist 4577106 To generate your key and secret is as simple as the following:

mkdir /some/working/dir
cd /some/working/dir

wget \
https://gist.github.com/raw/4577106/6bc9befedcd5238ce9f2ee562cace666dece460c/Gemfile

bundle install
bundle exec generate-token

One bit of useful flare is the ability to set the bindir in the gemspec of the microgem to dot "." - the current working directory. This allows bundle exec generate-token to work correctly since github gists don't allow files to be in sub-directories, and the default bindir in rubygems is 'bin/'.

Named placeholders in Active Record queries

Posted 4 months back at The Pug Automatic

As you likely know, Active Record supports placeholder values in queries:

<figure class="code">
1
User.where("email LIKE ? OR username LIKE ?", query, query)
</figure>

But it is perhaps less well-known that it also supports named placeholders:

<figure class="code">
1
2
User.where("email LIKE :query OR username LIKE :query", query: query)
User.where("(fooable = :true AND foo_id = :foo_id) OR (barable = :true AND bar_id = :bar_id)", true: true, foo_id: 123, bar_id: 456)
</figure>

These are great when you use the same value more than once, or to make complex queries more readable.

Opinionated settings for app development in Xcode

Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

Setting up a new Xcode project is as simple as ⇧⌘N. Unless you want to do things the right way, at which point there are a number of other configurations you need to worry about: .gitignore, .gitattributes, project level indentation settings, warning levels, etc. After doing the same setup procedure a few times, you can make it a relatively quick process. But it’s 2013, and we’re living in the future now. We have the technology to build tacocopters, but I still have to set my error levels manually? That’s just ridiculous.

Enter: liftoff.

liftoff-image

liftoff is a small Ruby gem that we’ve been working on to make new Xcode project setup as fast and painless as possible. With one simple command, you’ll have a slew of defaults set up for your project, along with some things that we think will make your life in Xcode a bit nicer.

Usage

First, install the gem, which is as simple as gem install liftoff. Then, while in your project directory (wherever you are keeping the .xcodeproj file), just run liftoff. This will set up the project defaults we like to use:

These commands can be run individually as well. For example, setting the project’s indentation level to 2 spaces can be done with liftoff indentation 2.

The best part about using liftoff over another solution like a custom project template is that liftoff can be used to quickly add these settings to an existing project without worrying about stomping on your current setup.

liftoff is currently at version 0.6 and, as usual, the code is open source on GitHub. We hope you enjoy it as much as we do.

Ruby Science: Improving Callbacks and Validations

Posted 4 months back at GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home

We have three new chapters to announce this week in Ruby Science. If you’re already reading Ruby Science, make sure to log into GitHub and download the latest version.

Here’s what’s new:

Code smells

  • Callback

Solutions

  • Extract Validator
  • Replace Callback with Method

The book is a work in progress, and currently contains around 76 pages of content. Purchasing the book also gets you access to the companion example application, as well as the ability to send thoughtbot your toughest Ruby, Rails, and refactoring questions.

If you haven’t already purchased it, you can still get access for the early purchase price of $39. In less than two weeks, the price will increase to $49.

Download a free sample of Ruby Science today.

Episode #337 - December 7th, 2012

Posted 4 months back at Ruby5

Ruby updates, testing your security with metasploit, Her, a RubyMotion tutorial, how ActiveRecord saves, Ember + RailsAPI = awesome, Spree news, and git_statistics in this RubyLoco edition of Ruby5.

Listen to this episode on Ruby5

This episode is sponsored by New Relic
Every time we look at the NewRelic blog they seem to be announcing new features. You can now monitor your applications from multiple regions within the U.S. so you can get even more information on your apps performance for your users. Thats right, availability monitoring now has multi-region uptime awareness! Get it today by going to http://NewRelic.com

Ruby 1.9.3-p374
This version of ruby 1.9.3 fixes the segfault issues discussed on episode #333.

Metasploit
Using metasploit, you can test to see if your application is still vulnerable to CVE-2013-0156, the yaml injection / arbitrary code execution vulnerability recently patched in rails.

Her
Her is an ORM (Object Relational Mapper) that maps REST resources to Ruby objects. It is designed to build applications that are powered by a RESTful API instead of a database.

Save Lifecycle
Rails does a lot for you on the save() call and Neeraj Singh dissected the lifecycle of the call and wrote a blog post about it.

Ember + RailsAPI
This three part tutorial by Brian Cardarella show how to use ember and the railsAPI gem to build an application.

Spree 1.3.1 + Fancy Theme
Spree 1.3.1 is a free, open source ecommerce platform written in Rails. The new version has a redesigned admin interface, an updated API, and improved international currency handling.

Ruby on iOS
Mario Chevez posted a long tutorial showing you how to build a Ruby Motion app for managing a conference. He shows you how to build an app using the command line tools like bundle and rake.

git_statistics