Aruba: Stubbing binaries

When testing your command line application with Aruba, you might need to stub out other binaries you don't want to be invoked by your test.

Aruba Doubles is a library that was built for this purpose. It is not actively maintained, but works with the little fix below.

Installation

Install the gem as instructed by its README, then put this Before block somewhere into features/support:

Before do
  Arub...

Hide a Rake task from the `rake -T` list

A Rake task appears in rake -T if it has a description:

desc 'Compile assets'
task :compile do
  ...
end

To not list it, simply omit the description:

task :compile do
  ...
end

You can also hide a Rake task that has been defined by someone else (like a gem) by removing the description:

Rake::Task['compile'].clear_comments

Or you can whitelist which tasks should be listed:

visible_tasks = %w(compile build package)
Rake::Task.tasks.each do |task|
  visible_tasks.include?(task.name) or task.clear_comments
en...

Ruby: Writing specs for (partially) memoized code

When you're writing specs for ActiveRecord models that use memoization, a simple #reload will not do:

it 'updates on changes' do
  subject.seat_counts = [5]
  subject.seat_total.should == 5
  # seat_total is either memoized itself, or using some
  # private memoized method
  
  subject.seat_counts = [5, 1]
  subject.seat_total.reload.should == 6 # => Still 5
end

You might be tempted to manually unmemoize any memoized internal method to get #seat_total to update, but that has two disadvant...

Subclassing module

Yesterday I stumbled across a talk in which the guy mentioned module sub-classing. I was curious what you can do with it and found his blog post with a cool example. It allows you to inject some state into the module you are including elsewhere. Check it out!

class AttributeAccessor < Module
  def initialize(name)
    @name = name
  end

  def included(model)
    super
    define_accessors
  end

  private

  def define_accessors
    ivar = "@#{@name}"
    define_writer(ivar)
    define_reader(ivar)
  end

  def define_writer(ivar)
    ...

How to monitor Sidekiq: A working example

In order to have monitoring for Sidekiq (like queue sizes, last run of Sidekiq) your application should have a monitoring route which returns a json looking like this:

{
  "sidekiq": {
    "totals": {
      "failed": 343938,
      "processed": 117649167
    },
    "recent_history": {
      "failed": {
        "2016-11-06": 1,
        "2016-11-07": 46,
        "2016-11-08": 0,
        "2016-11-09": 0,
        "2016-11-10": 0
      },
      "processed": {
        "2016-11-06": 230653,
        "2016-11-07": 230701,
        "2016-11-08"...

mceachen/closure_tree: Easily and efficiently make your ActiveRecord models support hierarchies

Closure_tree lets your ActiveRecord models act as nodes in a tree data structure.

This promises a few improvements over the battle-tested ancestry gem, such as:

  • Better performance
  • Pre-ordered trees (painful to do with ancestry)
  • Holds a mutex during tree manipulations (an issue with ancestry, where concurrent updates can cause deadlocks and corrupt data).

It has some more moving parts than ancestry though (see below).

Implementation
--------------...

Detecting if a Ruby gem is loaded

Detect if a gem has been activated

A gem is activated if it is either in the current bundle (Gemfile.lock), or if you have manually activated it using Kernel#gem (old-school).

To detect if e.g. activerecord has been activated:

if Gem.loaded_specs.has_key?('activerecord')
  # ActiveRecord was activated
end

Detect if a particular gem version has been activated

To detect if e.g. activerecord ma...

makandra/gemika: Helpers for testing Ruby gems

We have released a new library Gemika to help test a gem against multiple versions of Ruby, gem dependencies and database types.

Here's what Gemika can give your test's development setup (all features are opt-in):

  • Test one codebase against multiple sets of gem dependency sets (e.g. Rails 4.2, Rails 5.0).
  • Test one codebase against multiple Ruby versions (e.g. Ruby 2.1.8, Ruby 2.3.1).
  • Test one codebase against multiple database types (currently MySQL or PostgreSQL).
  • Compute a matrix of all possib...

Fix "libmysqlclient.so.20: cannot open shared object file: No such file or directory"

This error can be caused by the mysql2 gem under mysterious circumstances. You need to remove it with gem uninstall mysql2 and then reinstall it (or just run bundle).

gem pristine mysql2 will not be enough.

Measuring sql query time of a piece of code using ActiveSupport::Notifications

ActiveSupport::Notifications provides an instrumentation API for Ruby. It is used throughout rails to publish instrumentation events that include information about each part of a request/response cycle.

Have a look at your application log file - yes, those are those events. The cool thing is that you can subscribe to those events.

There is also a convenience method that allows you to subscribe to those events only for the time of executing a block of code. Thus you can capture all sql queries that are triggered when executing your block....

Isolate Side Effects in Ruby

In this article, we’ll look at what side effects are, why they are problematic despite being necessary, and how to isolate them to minimise their drawbacks.

Minidusen: Low-tech record filtering with LIKE queries

We have a new gem Minidusen which extracts Dusen's query parsing and LIKE query functionality.

Minidusen can no longer index text in MySQL FULLTEXT columns, which was hardly used and didn't always help performance due to the cost of reindexing.

Minidusen is currently compatible with MySQL, PostgreSQL, Rails 3.2, Rails 4.2 and Rails 5.0.

Basic Usage

Our example will be a simple address book:

class Contact < ActiveRecord::Base
  validates_presence_of :name, :street, :city, :e...

Capistrano: exclude custom bundle groups for production deploy

Capistrano is by default configured to exclude the gems of the groups development and test when deploying to the stages production and staging. Whenever you create custom groups in your Gemfile, make sure to exclude these, if they should not be deployed to the servers. The gems of these groups might not be loaded by rails, however, the deployment process will take longer as the gems will be downloaded and installed to the server.

e.g. to exclude the groups cucumber and deploy, add the following to `config/deploy/production.rb...

Incredibly fast web apps // Speaker Deck

Presentation about optimizing Ruby on Rails apps.

From Nico Hagenburger (homify's lead frontend developer).

Ruby: __FILE__, __dir__ and symlinks

Ruby's __FILE__ keyword returns the path to the current file. On popular for this are Ruby binaries:

#!/usr/bin/env ruby
$LOAD_PATH << File.expand_path('../../lib', __FILE__)
require 'my_cli'
MyCli.run!

However, if you create a symlink to this file, this will no longer work. __FILE__ will resolve to the path of the symlink, not to its target.

One solution is to use File.realpath(__FILE__).

In Ruby 2+ you can also use this:

$LOAD_PATH << File.expand_path('../lib', __dir__)

__dir__ is simply a shortcut for `...

Represent astral Unicode characters in Javascript, HTML or Ruby

Here is a symbol of an eight note: ♪

Its two-byte hex representation is 0x266A.

This card describes how to create a string with this symbol in various languages.

All languages

Since our tool chain (editors, languages, databases, browsers) is UTF-8 aware (or at least doesn't mangle bytes), you can usually get away with just pasting the symbol verbatim:

note = '♪'

This is great for shapes that are easily recognized by your fellow programmers.
It's not...

There is no real performance difference between "def" and "define_method"

You can define methods using def or define_method. In the real world, there is no performance difference.

define_method is most often used in metaprogramming, like so:

define_method :"#{attribute_name}_for_realsies?" do
  do_things
end

Methods defined via define_method are usually believed to have worse performance than those defined via def.
Hence, developers sometimes prefer using class_eval to define methods using def, like this:

class_eval "def #{attribute_name}_for_realsies?; do_things; end"

You can be...

has_one association may silently drop associated record when it is invalid

This is quite an edge case, and appears like a bug in Rails (4.2.6) to me.

Update: This is now documented on Edgeguides Ruby on Rails:

If you set the :validate option to true, then associated objects will be validated whenever you save this object. By default, this is false: associated objects will not be validated when this object is saved.

Setup

# post.rb
class Post < ActiveRecord::Base
  has_one :attachment
end
# attachm...

Ruby's default encodings can be unexpected

Note: This applies to plain Ruby scripts, Rails does not have this issue.

When you work with Ruby strings, those strings will get some default encoding, depending on how they are created. Most strings get the encoding Encoding.default_internal or UTF-8, if no encoding is set. This is the default and just fine.

However, some strings will instead get Encoding.default_external, notably

  • the string inside a StringIO.new
  • some strings created via CSV
  • files read from disk
  • strings read from an IRB

Encoding.default_external d...

Ruby 2.3 new features

Ruby 2.3.0 has been around since end of 2015. It brings some pretty nice new features! Make sure to read the linked post with its many examples!

Hash#fetch_values

Similar to Hash#fetch, but for multiple values. Raises KeyError when a key is missing.

attrs = User.last.attributes
attrs.fetch_values :name, :email

Hash#to_proc

Turns a Hash into a Proc that returns the corresponding value when called with a key. May be useful with enumerators like #map:

attrs.to_proc.call(:name)
attrs.keys.grep(/name/).map &attrs...

Download Ruby gems without installing

You can download .gem files using gem fetch:

gem fetch activesupport consul

This will produce files like active-support-5.0.0.gem and consul-0.12.1.gem in your working directory.

Dependencies will not be downloaded.

Ruby 2.3.0 has a safe navigation operator

As announced before, Ruby has introduced a safe navigation operator with version 2.3.0. receiver&.method prevents NoMethodErrors by intercepting method invocations on nil.

user = User.last
user&.name # => "Dominik"
# When there is no user, i.e. user is nil:
user&.name # => nil

This might remind you of andand, and indeed it behaves very similar. The only difference is in handling of `fa...

Ruby 2.3 brings Array#dig and Hash#dig

#dig lets you easily traverse nested hashes, arrays, or even a mix of them. It returns nil if any intermediate value is missing.

x = {
  foo: {
    bar: [ 'a', { baz: 'x' } ]
  }
}

x.dig(:foo, :bar) # => [ 'a', { baz: 'x' } ]
x.dig(:foo, :bar, 1, :baz) # => "x"
x.dig(:foo, :wronk, 1, :baz) # => nil

There is a tiny gem that backports this.

Testing terminal output with RSpec

When testing Ruby code that prints something to the terminal, you can test that output.
Since RSpec 3.0 there is a very convenient way to do that.

Anything that writes to stdout (like puts or print) can be captured like this:

expect { something }.to output("hello\n").to_stdout

Testing stderr works in a similar fashion:

expect { something }.to output("something went wrogn\n").to_stderr

Hint: Use heredoc to test multi-line output.

expect { something }.to output(<<-MESSAGE.strip_heredoc).to_stdout...