A Little Trailblazer Cookbook

Trailblazer is a high-level Architecture libraries for the Ruby web application (not only for Rails). If you are no familiar with it yet - take a 20 minutes walk through guide...

I want to cover once again those places where our team had issues or misunderstanding. Trailblazer documentation got a lot of improvements recently and keep getting more and more care. Some points from this list are covered by the docs, but in practice not everything was smooth.


Read more ...

Metaprogramming in Ruby lib: beauty vs usability

Recently I have evaluated different HTTP request wrapper libraries for Ruby project. Took 3 most popular: Faraday, RestClient, HTTParty. And found an interesting fact that illustrates very common issue in the world of Ruby libs.

Metaprogramming is used for the sake of Metaprogramming - "because it is Ruby and I can do it like this...". Not to make end-user developer life simpler.

Let's see the main purpose of HTTP request lib - is to send HTTP request (GET, POST, etc.). And the main purpose should dictate public interface of the lib classes. It should have a generic method to do any kind of HTTP request + shortcut methods to do the most common requests, like GET and POST.

That is what all these libs have

# kind-a this
connection.get(url)
# or this
Client.post(url, body_params_hash)
# it doesn't really matter is it static or object method

The issue is - these methods get/post are not real. For some reasons lib author try to spare 10 lines of code, but to use "cool Metaprogramming approach". The consequences of this - I am as an end-user of this lib, can't Ctrl+Click on post method in my IDE to see how it is implemented and what's happen inside. Because this method does not really exist in class, it appears in runtime after class_eval or define_method. I can't even find the place in Gem where it defined without getting deep in internal implementation. That is a bit frustrating for me. These 3-5 methods are the most important parts of such a lib, I don't care about all other parts, but exactly these parts are hidden from me. And for what good reason?

Proof Faraday

 %w[get head delete].each do |method|
      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        def #{method}(url = nil, params = nil, headers = nil)
          run_request(:#{method}, url, nil, headers) { |request|
            request.params.update(params) if params
            yield(request) if block_given?
          }
        end
      RUBY
    end

Proof RestClient

POSSIBLE_VERBS = ['get', 'put', 'post', 'delete']
...
POSSIBLE_VERBS.each do |m|
  define_method(m.to_sym) do |path, *args, &b|
    r[path].public_send(m.to_sym, *args, &b)
  end
end

Only HTTParty has explicit declaration of these methods . Thank you guys, you rock! :)

...
    def get(path, options = {}, &block)
      perform_request Net::HTTP::Get, path, options, &block
    end
...

As we can see it is 3-5 line methods. There is no any problem to write them explicitly and hardcode method name inside them + extract all repeating lines inside a separate method. That is absolutely normal code design approach. Instead of sacrificing code simplicity and readability of favor of code size.


Read more ...

SSH auth for multiple GitHub accounts on OSX

When you use more than one SSH key to access GitHub you can use primary account by default and additional, with such a config (assume your second SSH key file is ~/.ssh/id_rsa_pewpew)

Host github-pewpew
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_pewpew

With Linux having ssh key in .ssh folder and configuring ~/.ssh/configis enough. But on MacOS I get an error during Git clone (and Capistrano deploy) like this:

git clone git@github-pewpew:.../...git
Cloning into 'MyRepo'...
ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights and the repository exists.

a bit confusing, but an error is not with Repo by itself (if you are completely sure that you are the repo owner or have write-rights).

Solution

On MacOS X I need to additional keys manually by

$ ssh-add ~/.ssh/id_rsa_pewpew

and you can check what key are in use right now

$ ssh-add -l

Note

On MacOS X you will need to add key after every system restart. It looks like we need to use OSX Keychain to reload them authomatically via

$ ssh-add -K [path/to/private SSH key]


Ruby (on Rails) ecosystem bittersweet or "we like to hate PHP"

tl;dr;
I am putting some facts and personal experience to prove that PHP has healthier, more competitive and loosely-coupled ecosystem, than Ruby. I am talking about Performance, Syntax and Coding aspects, Community and Tools support.

If you want to skip a lot of empty rant - scroll till the "The main part goes here..." heading :) But I need to say all of this...

What? Yet another anti-RoR rant?

Yep, I started to gather materials for this posts more than 6 months ago, and I know about all that discussions that are going around RoR's pros and cons recent weeks. The main are "My time with Rails is up" and Rails has won: The Elephant in the Room. I am definitely not so experienced in RoR to say something new, that hasn't been said yet in terms of architecture. I just want to argue on Rails leadership in web development.

[PHP] ... fragmented, independent and isolated communities ... is one big ocean of disconnected islands.

Says AkitaOnRails, and as always that's true from one side, but not true - from another. Dear Rubyists let me show you the world of the closest competitor - PHP. And there is nothing special in Ruby for "Basecamp-like" app, that we can't find in PHP.


Read more ...
Ievgen
Kuzminov "iJackUA"
Web Team Lead
at MobiDev (Kharkiv, Ukraine)
Code in PHP and Ruby, play with JS/Node.JS, evaluate Elixir, explore databases, use Ubuntu and MacOS, think about IT people and management

Notes


Framework functionality that is not related to merely taking input from a Request and presenting output through a Response becomes entirely secondary to, perhaps even actively harmful to, building well-structured applications... [more]