Tuesday, March 15, 2016

Rails 5 New Project Options

$ rails new --help
Usage:
  rails new APP_PATH [options]

Options:
  -r, [--ruby=PATH]                                      # Path to the Ruby binary of your choice
                                                         # Default: /Users/bparanj/.rvm/rubies/ruby-2.3.0/bin/ruby
  -m, [--template=TEMPLATE]                              # Path to some application template (can be a filesystem path or URL)
  -d, [--database=DATABASE]                              # Preconfigure for selected database (options: mysql/oracle/postgresql/sqlite3/frontbase/ibm_db/sqlserver/jdbcmysql/jdbcsqlite3/jdbcpostgresql/jdbc)
                                                         # Default: sqlite3
  -j, [--javascript=JAVASCRIPT]                          # Preconfigure for selected JavaScript library
                                                         # Default: jquery
      [--skip-gemfile], [--no-skip-gemfile]              # Don't create a Gemfile
  -B, [--skip-bundle], [--no-skip-bundle]                # Don't run bundle install
  -G, [--skip-git], [--no-skip-git]                      # Skip .gitignore file
      [--skip-keeps], [--no-skip-keeps]                  # Skip source control .keep files
  -M, [--skip-action-mailer], [--no-skip-action-mailer]  # Skip Action Mailer files
  -O, [--skip-active-record], [--no-skip-active-record]  # Skip Active Record files
  -P, [--skip-puma], [--no-skip-puma]                    # Skip Puma related files
  -C, [--skip-action-cable], [--no-skip-action-cable]    # Skip Action Cable files
  -S, [--skip-sprockets], [--no-skip-sprockets]          # Skip Sprockets files
      [--skip-spring], [--no-skip-spring]                # Don't install Spring application preloader
      [--skip-listen], [--no-skip-listen]                # Don't generate configuration that depends on the listen gem
  -J, [--skip-javascript], [--no-skip-javascript]        # Skip JavaScript files
      [--skip-turbolinks], [--no-skip-turbolinks]        # Skip turbolinks gem
  -T, [--skip-test], [--no-skip-test]                    # Skip test files
      [--dev], [--no-dev]                                # Setup the application with Gemfile pointing to your Rails checkout
      [--edge], [--no-edge]                              # Setup the application with Gemfile pointing to Rails repository
      [--rc=RC]                                          # Path to file containing extra configuration options for rails command
      [--no-rc], [--no-no-rc]                            # Skip loading of extra configuration options from .railsrc file
      [--api], [--no-api]                                # Preconfigure smaller stack for API only apps

Runtime options:
  -f, [--force]                    # Overwrite files that already exist
  -p, [--pretend], [--no-pretend]  # Run but do not make any changes
  -q, [--quiet], [--no-quiet]      # Suppress status output
  -s, [--skip], [--no-skip]        # Skip files that already exist

Rails options:
  -h, [--help], [--no-help]        # Show this help message and quit
  -v, [--version], [--no-version]  # Show Rails version number and quit

Description:
    The 'rails new' command creates a new Rails application with a default
    directory structure and configuration at the path you specify.

    You can specify extra command-line arguments to be used every time
    'rails new' runs in the .railsrc configuration file in your home directory.

    Note that the arguments specified in the .railsrc file don't affect the
    defaults values shown above in this help message.

Example:
    rails new ~/Code/Ruby/weblog

    This generates a skeletal Rails installation in ~/Code/Ruby/weblog.

Wednesday, March 09, 2016

Symbol to_proc Hack

Usually, when we create a proc, the proc object captures the variables that is in the creation context. However, in Symbol#to_proc,  the object obj that is in:

Proc.new {|obj| obj.send(self) }

is not in the surrounding context of the proc object. At this point there is no 'obj' object. So, within the Symbol class to_proc method, there is no obj. When the & ampersand trigger is executed, the map method yields a block variable, this block variable gets associated to the obj object. This is a subtle concept. We can bind values to the block variable in the proc object at run-time. This is a very powerful concept we can use when we develop libraries.


Tuesday, March 08, 2016

Trace Route on Mac OS

$ traceroute www.rubyplus.com

traceroute to www.rubyplus.com (198.58.102.13), 64 hops max, 52 byte packets
 1  10.33.0.1 (10.33.0.1)  0.760 ms  0.245 ms  0.252 ms
 2  209.133.4.85 (209.133.4.85)  0.456 ms  0.522 ms  0.516 ms
 3  ae5.cr2.sjc2.us.zip.zayo.com (64.125.26.21)  2.386 ms  4.013 ms  3.053 ms
 4  ae16.mpr4.sjc7.us.zip.zayo.com (64.125.31.15)  1.757 ms  1.909 ms  1.868 ms
 5  209.133.4.46 (209.133.4.46)  1.914 ms  1.945 ms  1.971 ms
 6  ae0.bbr02.cs01.lax01.networklayer.com (173.192.18.151)  10.292 ms  10.630 ms  10.217 ms
 7  ae7.bbr01.cs01.lax01.networklayer.com (173.192.18.166)  10.367 ms  10.220 ms  10.698 ms
 8  ae19.bbr01.eq01.dal03.networklayer.com (173.192.18.140)  40.263 ms  37.674 ms  40.394 ms
 9  po31.dsr02.dllstx3.networklayer.com (173.192.18.227)  38.005 ms  37.520 ms  40.913 ms
10  po32.dsr02.dllstx2.networklayer.com (70.87.255.70)  41.327 ms  37.968 ms
    po31.dsr01.dllstx2.networklayer.com (70.87.255.66)  40.557 ms
11  po1.car02.dllstx2.networklayer.com (70.87.254.82)  37.646 ms
    po2.car01.dllstx2.networklayer.com (70.87.254.78)  37.714 ms
    po2.car02.dllstx2.networklayer.com (70.87.254.86)  41.112 ms
12  router2-dal.linode.com (67.18.7.94)  37.950 ms  40.729 ms
    router1-dal.linode.com (67.18.7.90)  41.317 ms
13  www.rubyplus.com (198.58.102.13)  41.468 ms  41.386 ms  37.602 ms

Dependency Inversion Principle Example from The RSpec Book

The code example for Codebreaker game from The Rspec Book. The solution in the book that does not apply the DIP

Before

module Codebreaker
  class Game
    def initialize(output)
      @output = output
    end

    def start(secret)
      @secret = secret
      @output.puts 'Welcome to Codebreaker!'
      @output.puts 'Enter guess:'
    end
  end
end

g = Codebreaker::Game.new($stdout)
g.start('sekret')

The solution after applying the DIP.

After

module Codebreaker
  class Game
    def initialize(writer)
      @writer = writer
    end

    def start(secret)
      @secret = secret
      @writer.write 'Welcome to Codebreaker!'
      @writer.write 'Enter guess:'
    end
  end
end

class StandardConsole
  def write(message)
    $stdout.puts(message)
  end 
end

writer = StandardConsole.new
g = Codebreaker::Game.new(writer)
g.start('sekret')

List Untracked Files in Git

git ls-files --others --exclude-standard

You can chain this to xargs:

git ls-files --others --exclude-standard | xargs git rm

to remove those files.

Monday, March 07, 2016

Dependency Inversion Principle

The article

The Three Basic Rules for a Good Design

illustrates the Dependency Inversion Principle in action by using a simple example. It applies three simple rules:

  1. Separate things that change from things that stays the same. Encapsulate what varies behind a well-defined interface.
  2. Program to interfaces, not implementations. This exploits polymorphism.
  3. Depend on abstractions. Do not depend on concrete classes.
to satisfy Dependency Inversion Principle. 

Storage mechanisms such as PersonMemoryStore and PersonFileStore have a well defined interface called records. The mechanisms to send the message such as GreetingConsole and GreetingPony have a well defined interface call send. Classes that implement a specific storage or sending email now conform to a uniform interface. This gives us the ability to switch implementation in different combinations. The classes that implement specific way of doing things depend on stable abstractions, records and send that we came up with in the final design.

Saturday, March 05, 2016

Compress Custom Web Fonts in Rails 4.2.5 Apps

 The easiest way to compress custom web fonts in a Rails 4.2.5 app is to use Amazon Cloudfront. In your Cloudfront configuration, select Yes for Compress Objects Automatically.


Here you can see the result of Web Page Performance Test for RubyPlus after the Custom Web fonts has been compressed. It takes 30 minutes or so for the cloudfront configuration changes to take effect.

Amazon Docs

Friday, March 04, 2016

Caching Database Results in Rails 4.2.5

If you make the same database calls  within any one request, Rails will cache the database result. You don't need to use use ||= to cache the value.
  def show
    Article.find(params[:id])
    Article.find(params[:id])
  end

You can see that the cache is hit in the log file:

Started GET "/articles/1" for ::1 at 2016-03-03 16:42:13 -0800
Processing by ArticlesController#show as */*
  Parameters: {"id"=>"1"}
  Article Load (0.1ms)  SELECT  "articles".* FROM "articles" WHERE "articles"."id" = ? LIMIT 1  [["id", 1]]
  CACHE (0.0ms)  SELECT  "articles".* FROM "articles" WHERE "articles"."id" = ? LIMIT 1  [["id", "1"]]
  Rendered articles/show.html.erb within layouts/application (0.3ms)
Completed 200 OK in 25ms (Views: 24.0ms | ActiveRecord: 0.1ms)

From  the Caching with Rails guide.

SQL Caching

Query caching is a Rails feature that caches the result set returned by each query so that if Rails encounters the same query again for that request, it will use the cached result set as opposed to running the query against the database again.

Thursday, March 03, 2016

Compress all Assets using GZip

In production.rb:

use Rack::Deflater

https://remino.net/rails-html-css-js-gzip-compression/

Wednesday, March 02, 2016

Compress Html to Improve Rails 4.2.5 App Performance

1. Add htmlcompressor gem to Gemfile.

group :production do
  gem 'htmlcompressor'
end

Run bundle install.

2. In production.rb:

  config.middleware.use HtmlCompressor::Rack

3. Deploy and enjoy the speed.


GTmetrix.com test score for html compression went up. But the performance went down. The page load time went up to 2.1 seconds from 1.7 seconds.

Can't initialize a new Rails application within the directory of another, please change to a non-Rails directory first.

This error happens if any of the directory in which you are running rails new has some rails directory structure. Resolution: Go to a directory that does not have any rails directory structure.

Can the genius Rails committers provide the resolution as part of the error message please?

Tuesday, March 01, 2016

Using Asset Pipeline for Favicons in Rails 4.2.5

1. Copy icon images to app/assets/images folder.

2. Use favicon_link_tag helper. Default image name : favicon.ico.
   
      <%= favicon_link_tag %>
  <%= favicon_link_tag 'apple-touch-icon-57x57.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "57x57" %>
  <%= favicon_link_tag 'apple-touch-icon-60x60.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "60x60" %>
  <%= favicon_link_tag 'apple-touch-icon-72x72.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "72x72" %>
  <%= favicon_link_tag 'apple-touch-icon-76x76.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "76x76" %>
  <%= favicon_link_tag 'apple-touch-icon-114x114.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "114x114" %>    
  <%= favicon_link_tag 'apple-touch-icon-120x120.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "120x120" %>
  <%= favicon_link_tag 'apple-touch-icon-144x144.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "144x144" %>
  <%= favicon_link_tag 'apple-touch-icon-152x152.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "152x152" %>
  <%= favicon_link_tag 'apple-touch-icon-180x180.png', rel: 'apple-touch-icon', type: 'image/png', sizes: "180x180" %>
  <%= favicon_link_tag 'favicon-32x32.png', rel: 'icon', type: 'image/png', sizes: "32x32" %>          
  <%= favicon_link_tag 'android-chrome-192x192.png', rel: 'icon', type: 'image/png', sizes: "192x192" %>          
  <%= favicon_link_tag 'favicon-96x96.png', rel: 'icon', type: 'image/png', sizes: "96x96" %>          
  <%= favicon_link_tag 'favicon-16x16.png', rel: 'icon', type: 'image/png', sizes: "16x16" %>            


3. Verify by viewing the page source.

  <link rel="shortcut icon" type="image/x-icon" href="https://d1b5oz78c0udqh.cloudfront.net/assets/favicon-0784d42434f39fe96f3736f3e47d1e9f.ico" />
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-57x57-1f87fa73399b81c63cf77fee620b3f25.png" sizes="57x57" />
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-60x60-421e797d9dc30906f3876c0bf72c8e98.png" sizes="60x60" />
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-72x72-53f33feccdeb7a9428d3bfd3f9fdcb5c.png" sizes="72x72" />  
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-76x76-8d6db4af70c6c952ffbc34e742035187.png" sizes="76x76" />  
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-114x114-308d3819dfb621285ab6368f672a72fb.png" sizes="114x114" />      
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-120x120-15eedd3461f483a5b27828fa9ed789de.png" sizes="120x120" />  
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-144x144-5759a401867e2dfe239149695d7cd081.png" sizes="144x144" />  
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-152x152-9f15e1c9218a79ee781a128e8bfba79a.png" sizes="152x152" />  
  <link rel="apple-touch-icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/apple-touch-icon-180x180-2fc81325eec91ad63efb7d10ae0e1089.png" sizes="180x180" />  
  <link rel="icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/favicon-32x32-e6eebf5633792e63508f58260cfc98c6.png" sizes="32x32" />            
  <link rel="icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/android-chrome-192x192-b03a39be430b547b8448857ef3ed1960.png" sizes="192x192" />            
  <link rel="icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/favicon-96x96-93f5bc8d5e587ff2a07f4f6ea8349b09.png" sizes="96x96" />            
  <link rel="icon" type="image/png" href="https://d1b5oz78c0udqh.cloudfront.net/assets/favicon-16x16-ecb043d6bec4bf88aa1435bfa04000c2.png" sizes="16x16" />              

This should take the CDN for all static assets score from 90/100 to 100/100 on WebPageTest.

Monday, February 29, 2016

Upgrading from Passenger 4.0.60 to 5.0.25

If you are managing your Rails 4.2.5 server using Moonshine, follow these steps.

Step 1

In passenger.rb, within Moonshine::Manifest::Rails::Passenger module, change the passenger version:

```ruby
BLESSED_VERSION = '5.0.25'
```

Step 2

Add the following Capistrano 2 task to deploy.rb:

namespace :deploy do
  task :restart, :roles => :app, :except => { :no_release => true } do
    sudo "passenger-config restart-app --ignore-app-not-running /srv//current"
  end
end

Checkin the code changes to git and deploy the app using Capistrano.

Step 3

On the server, verify the installed version:

```sh
passenger-config --version
```

Page Load Time

In passenger 4.0.60, it took 2.4 s
In passenger 5.0.25, it took 1.7 s


Turn on Keepalive to Speed Up Rails 4.2.5 App

I am using Moonshine to manage Rails 4.2.5 app RubyPlus on Linode. In Moonshine source code, file apache.rb, change the keep_alive to 'on':

 defaults = {
    :keep_alive => 'on',
 
Linode provides 2 GB of RAM for just $20/month. So, there is no reason not to turn on this setting. Especially for low traffic sites. This setting will keep the connection open so that all assets can be downloaded in one connection. This avoids opening multiple connection to the server by the browser to download the assets.

Moonshine Support for Passenger 5

1. Passenger 5 support added in : lib/moonshine/manifest/rails/passenger.rb
2. To restart the app with capistrano 2 add the following to your config/deploy.rb file:

namespace :deploy do
  task :restart, :roles => :app, :except => { :no_release => true } do
    sudo "passenger-config restart-app --ignore-app-not-running /srv//current"
  end
end


https://github.com/railsmachine/moonshine/pull/240

Using Custom Web Fonts in Rails 4.2.5 Apps


I was getting this error after hooking up Amazon Cloudfront CDN for RubyPlus. Here are the steps to make Rails 4.2.5 use custom fonts.

1. In:

config/application.rb 

config.assets.paths << Rails.root.join("app", "assets", "fonts")

2.  In your .scss files, change the src to use font-url not url:

@font-face {
    font-family: 'icofonts';
    src:font-url('fonts/icofonts.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
}   
3.  In Moonshine source code, file apache.rb, add 'application/x-font-ttf', 'font/ttf' to the end of the gzip_types:

 defaults = {
    :gzip_types => ['text/html', 'text/plain', 'text/xml', 'text/css', 'text/javascript', 'text/json', 'application/x-javascript', 'application/javascript', 'application/json', 'application/x-font-ttf', 'font/ttf' ]


Reference:

Custom Web Fonts and the Rails Asset Pipeline



Thursday, February 25, 2016

retry

attempts = 0
begin
  raise
rescue
  attempts += 1
  puts 'retrying...'
  retry if attempts < 3
end


def work
  with_retry do
    puts 'working...'
    raise
  end
end

def with_retry
  attempts = 0
  begin
    yield
  rescue
    attempts += 1
    puts 'retrying...'
    if attempts < 3
      retry
    else
      puts 'Giving up!'
    end
  end
end

work

Tuesday, February 23, 2016

Performance of a.length > 0 vs a.empty? on

In Ruby 2.3.0

require 'benchmark'

a = []

t1 = Benchmark.realtime do
 a.length > 0
end

t2 = Benchmark.realtime do
  a.empty?
end

p t2 < t1


This prints true.



Tuesday, February 16, 2016

Symbol vs String

Symbol is like country names and string is like city names that are not unique. There is Richmond city in California as well as Virginia. This is an example for strings that have the same content but are in different memory locations. State name is unique, there is only one california in USA.

Filter out sensitive parameters from logging file in Rails 4.2.5

Create filter_parameter_logging.rb in config/initializers folder:

Rails.application.config.filter_parameters += [:password, :password_confirmation]





Tuesday, February 02, 2016

Thoughts on Sandi Metz presentation

Returning nil in the absence of some object means the type changes. Not all of them are ducks. One of them is going to be NilClass. This will not be able to respond to the message sent by the client.

This problem is because the return type from a method is not uniform. If it always returns an object that can respond to a certain message sent by a client, then the program will not crash.

In Java, we can declare interface. Something like this:

interface OperateCar {
  int turn(direction)
}

You can see that the return type of the turn method is integer. The clients can depend on this fact. They need not worry about handing a null for instance. Since the interface is implicit in Ruby, it allows returning different types of objects, this leads to problems. The only way to make the client code simpler is to make the implementation return something that has consistent interface.

What are the components of an interface?
How can we write code to express the interface ?
Seems like the code will be implicit when it has to express the uniformity or the protocol.
What is a protocol?
What is an interface?

Monday, February 01, 2016

Dave Thomas Presentation Notes

Class names are constant. Why?
Classes are objects.
Class name can be assigned to a variable and used to create an instance.

irb
2.2.4 :001 > String.name
 => "String"
2.2.4 :002 > Class.name
 => "Class"
2.2.4 :003 > BasicObject.name
 => "BasicObject"
2.2.4 :004 > self.name
NoMethodError: undefined method `name' for main:Object
    from (irb):4
    from /Users/bparanj/.rvm/rubies/ruby-2.2.4/bin/irb:11:in `
'
2.2.4 :005 > self.to_s
 => "main"

 String.to_s
 => "String"
2.2.4 :007 > Class.to_s
 => "Class"
2.2.4 :008 > BasicObject.to_s
 => "BasicObject"


Instance variables are stored in current instance.


In the middle of the class, the code is running.
Every method call has a receiver.


puts does not have explicit receiver.
Default object, is always the self (the current object)
We did not create any object. We ask main :
What is the class that is used to create an instance of main?


Methods are not objects. It can be converted to an object.
puts can be converted into an object and we can call puts.

What is the current object?

Example.

No compilation phase.
Definitions are active.
There is always a receiver.

Class definitions is executable.
Everything gets executed.


Instead of doing:

Calling an utility method:

Encryptor.encrypt('secret')

vs

'secret'.encrypt

Sending a message

module Some

end

Some.new

vs

Module.new

class Object


  def to_s
    'main'
  end
end


class Person

  puts self
  puts self.class

end

class Person

  def self.talk
  end

end


class Person

  def self.talk
  end

  Person.talk
end



class Person

  def self.talk
  end

  self.talk

end


class Person

  def self.talk
  end

  talk

end


class Person

  def self.talk
  end

end

Person.talk


class Dumbass < Person

  talk

end

Notes from Smalltalk Presentation by Dan

The real power is in the messaging. The message name represents what and the implementation is hidden behind the method.

Break complex problem down into:

As few parts as possible as independent as possible.
Easier to learn because fewer components.
Productive because the components are re-usable.

Simplicity and Generality

Analysis

Small number of independent parts

Synthesis

Easy to learn
Productive
Maintainable (Built with fewer components)

factorial
self <= 1
  ifTrue: []
 
 
self = 0 ifTrue: [^ 1].
self > 0 ifTrue: [^ self * (self - 1) factorial].
self error: 'Not valid for negative integers'


recFact
self < 0
     ifTrue : [^0]
     ifFalse: [
         self = 0
             ifTrue : [^1]
             ifFalse: [^self * (self -1) recFact]
              ]


Instead of :

loop do
 p 'This will print forever'
end

[ code ] repeat

Ruby Equivalent

(Block Object).repeat

Ignore knowledge about objects. Focus on messages.


Smalltalk

Wednesday, January 27, 2016

Installing Scheme 9.2 on Mac OS 10.10.5

1. Download 64-bit installer mit-scheme-9.2-x86-64.dmg
2. Install Scheme.
3. sudo ln -s /Applications/MIT\:GNU\ Scheme.app/Contents/Resources /usr/local/lib/mit-scheme-x86-64
4. sudo ln -s /usr/local/lib/mit-scheme-x86-64/mit-scheme /usr/local/bin/scheme
5. Type scheme on the terminal.

undefined method `want=' for nil:NilClass (NoMethodError)

In Rails 4.2, you can define your own application specific custom variables in development.rb, test.rb and so on. If you define this:

  config.x.whatever.value.want = 42

It throws the error : undefined method `want=' for nil:NilClass (NoMethodError)

It seems to work only for two levels, so, this will work:

  config.x.whatever.value = 42

You can access the value like this:

Rails.configuration.x.whatever.value

You need to define the custom values by using 'config.x'.

Thursday, January 21, 2016

Error in The Well Grounded Rubyist Book

David Black says "The only circumstances under which you can omit the receiver are precisely the circumstance in which it's ok to call a private method."

 This is not true because we can omit the receiver when we call the class method declared in the superclass. ActiveRecord has_many declaration is an example.

Tuesday, January 19, 2016

Looking for Ruby Book Reviewers

I am looking for technical reviewers to review Essential Ruby Kindle book. I will mention your name and give a link to your site or blog  in the book. If you are interested, please contact me at bparanj at gmail dot com or RubyPlus contact form.

Tuesday, January 12, 2016

How to find out if a name is reserved in Rails 4.2.5

One of the articles that gets lot of traffic is : Reserved Words in Rails. If you do not use the generator to generate the code in your Rails project, you could potentially have class collision during runtime of your application. Here are the steps I followed:

1. I browsed the railties gem and searched for 'reserved by Ruby on Rails' to find where in the source code the check is done.
2. It is defined in the class rails/generators/base.rb in class_collisions(*class_names) protected method.
3. I went to the rails console to figure out how to use this method:

> require 'rails/generators/base'
NameError: uninitialized constant Rails::Generators::Actions
from /Users/bparanj/.rvm/gems/railties-4.2.5/lib/rails/generators/base.rb:17:in `'
pry(main)> require 'rails/generators/actions'
=> true
 pry(main)> require 'rails/generators/base'
=> true
 pry(main)> g = Rails::Generators::Base.new
=> # @_initializer=[[], {}, {}],
 @_invocations={},
 @after_bundle_callbacks=[],
 @args=[],
 @behavior=:invoke,
 @destination_stack=["/Volumes/Work/dev/ewok"],
 @in_group=nil,
 @options={},
 @shell=#, @mute=false, @padding=0>>
 pry(main)> g.send(:class_collisions, 'ActiveRecord')
Rails::Generators::Error: The name 'ActiveRecord' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative and run this generator again.
pry(main)> g.send(:class_collisions, 'type')
=> ["type"]
pry(main)> g.send(:class_collisions, 'ActiveRecord', 'ActiveJob')
Rails::Generators::Error: The name 'ActiveRecord' is either already used in your application or reserved by Ruby on Rails. Please choose an alternative and run this generator again.



Methods Live in Class

$ irb
2.2.4 :001 > s = 'hi'
 => "hi"
2.2.4 :002 > s.methods
 => [:<=>, :==, :===, :eql?, :hash, :casecmp, :+, :*, :%, :[], :[]=, :insert, :length, :size, :bytesize, :empty?, :=~, :match, :succ, :succ!, :next, :next!, :upto, :index, :rindex, :replace, :clear, :chr, :getbyte, :setbyte, :byteslice, :scrub, :scrub!, :freeze, :to_i, :to_f, :to_s, :to_str, :inspect, :dump, :upcase, :downcase, :capitalize, :swapcase, :upcase!, :downcase!, :capitalize!, :swapcase!, :hex, :oct, :split, :lines, :bytes, :chars, :codepoints, :reverse, :reverse!, :concat, :<<, :prepend, :crypt, :intern, :to_sym, :ord, :include?, :start_with?, :end_with?, :scan, :ljust, :rjust, :center, :sub, :gsub, :chop, :chomp, :strip, :lstrip, :rstrip, :sub!, :gsub!, :chop!, :chomp!, :strip!, :lstrip!, :rstrip!, :tr, :tr_s, :delete, :squeeze, :count, :tr!, :tr_s!, :delete!, :squeeze!, :each_line, :each_byte, :each_char, :each_codepoint, :sum, :slice, :slice!, :partition, :rpartition, :encoding, :force_encoding, :b, :valid_encoding?, :ascii_only?, :unpack, :encode, :encode!, :to_r, :to_c, :unicode_normalize, :unicode_normalize!, :unicode_normalized?, :>, :>=, :<, :<=, :between?, :nil?, :!~, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :singleton_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]
2.2.4 :003 > s.instance_methods
NoMethodError: undefined method `instance_methods' for "hi":String
    from (irb):3
    from /Users/bparanj/.rvm/rubies/ruby-2.2.4/bin/irb:11:in `
'
2.2.4 :004 > String.instance_methods
 => [:<=>, :==, :===, :eql?, :hash, :casecmp, :+, :*, :%, :[], :[]=, :insert, :length, :size, :bytesize, :empty?, :=~, :match, :succ, :succ!, :next, :next!, :upto, :index, :rindex, :replace, :clear, :chr, :getbyte, :setbyte, :byteslice, :scrub, :scrub!, :freeze, :to_i, :to_f, :to_s, :to_str, :inspect, :dump, :upcase, :downcase, :capitalize, :swapcase, :upcase!, :downcase!, :capitalize!, :swapcase!, :hex, :oct, :split, :lines, :bytes, :chars, :codepoints, :reverse, :reverse!, :concat, :<<, :prepend, :crypt, :intern, :to_sym, :ord, :include?, :start_with?, :end_with?, :scan, :ljust, :rjust, :center, :sub, :gsub, :chop, :chomp, :strip, :lstrip, :rstrip, :sub!, :gsub!, :chop!, :chomp!, :strip!, :lstrip!, :rstrip!, :tr, :tr_s, :delete, :squeeze, :count, :tr!, :tr_s!, :delete!, :squeeze!, :each_line, :each_byte, :each_char, :each_codepoint, :sum, :slice, :slice!, :partition, :rpartition, :encoding, :force_encoding, :b, :valid_encoding?, :ascii_only?, :unpack, :encode, :encode!, :to_r, :to_c, :unicode_normalize, :unicode_normalize!, :unicode_normalized?, :>, :>=, :<, :<=, :between?, :nil?, :!~, :class, :singleton_class, :clone, :dup, :itself, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :frozen?, :methods, :singleton_methods, :protected_methods, :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, :extend, :display, :method, :public_method, :singleton_method, :define_singleton_method, :object_id, :to_enum, :enum_for, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__]

Monday, January 11, 2016

Changing Self inside the Block

(1..10).tap {|x| puts "original: #{x.inspect}"}.tap {|x| puts "Original class: #{x.class}"}.to_a.tap {|x| puts "array: #{x.inspect}"}.tap {|x| puts "After class: #{x.class}"}

Wednesday, December 23, 2015

Test Rails 4.2.5 ActionMailer Settings

require 'action_mailer'

ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
   :address   => "smtp.gmail.com",
   :port      => 587,
   :domain    => "rubyplus.com",
   :authentication => :plain,
   :user_name      => "bparanj@rubyplus.com",
   :password       => "password",
   :enable_starttls_auto => true
  }
ActionMailer::Base.view_paths= File.dirname(__FILE__)

class Mailer < ActionMailer::Base

  def daily_email
    @var = "var"

    mail(   :to      => "bparanj@something.com",
            :from    => "bparanj@szy.com",
            :subject => "testing mail") do |format|
                format.text
                format.html
    end
  end
end

email = Mailer.daily_email.deliver_now
puts email
email.deliver

In mailer/daily_email.html.erb and mailer/daily_email.text.erb

this is an html email

and this is a variable <%= @var %>

this is a text email

and this is a variable <%= @var %>


Monday, December 21, 2015

How to include URL Helpers in Decorators in Rails 4.2.5

Add :
 
include Rails.application.routes.url_helpers
 
to the decorator. For example:
 
class BugsDecorator < ApplicationDecorator
  include Rails.application.routes.url_helpers
end 

Wednesday, December 16, 2015

ack options to list only file names

-w - Search whole word
-l  - Only print the filenames of matching files
-r - Recurse into subdirectories

ack -lrw '< MySuperClassName' --ignore-dir={app/assets,log,spec,vendor,public,coverage,config}

You can chain this to xargs to open all the matching file for editing like this:

ack -lrw '< MySuperClassName' --ignore-dir={app/assets,log,spec,vendor,public,coverage,config} | xargs mate


Sunday, December 13, 2015

Rails Performance Tools Presentation Notes

Tools for Linux

lsof
strace
ltrace

Tools for C Code

perftools
gdb

Tools for Networks

tcpdump
ngrep

Tools for CPU Usage

perftools
perftools.rb

Tools for Memory Usage

bleak_house
gdb.rb
memprof

LSOF

List open files

lsof -nPp

-n : Inhibits the conversion of network numbers to host names.
-P : Inhibits the conversion of port numbers to names for network files

TCP Dump

Dump traffic on a network

tcpdump -i eth0 -s 0 -nqA
tcp dst port 3306

Mammals

Mammals have hair or fur
Nurse their young with milk
have lungs and need air to breathe
Mammals that live on land have 4 legs and ears that stick out
Warm Blooded

Eg : Polar Bear, Gorilla, Horses etc

How to commit all deleted files in Git without affecting other modified files?

git ls-files --deleted | xargs git rm

Implementing Abs using Objects



def absolute(x)
  if x > 0
    x
  elsif x == 0
    0
  elsif x < 0
    -x
  end
end

# p absolute(0)


class GreaterThan
  attr_reader :number

  def initialize(value, number)
    @value, @number = value, number
  end

  def evaluate
    result[@number.send(:>, @value).class]
  end

  private

  def result
    {TrueClass => @number}
  end
end

# c = GreaterThan.new(0, -2)
#
# p c.evaluate

class LessThan
  attr_reader :number

  def initialize(value, number)
    @value, @number = value, number
  end

  def evaluate
    result[@number.send(:<, @value).class]
  end

  private

  def result
    {TrueClass => -@number}
  end
end


# c = LessThan.new(0, -2)
#
# p c.evaluate


class EqualTo
  attr_reader :number

  def initialize(value, number)
    @value, @number = value, number
  end

  def evaluate
    result[@number.send(:==, @value).class]
  end

  private

  def result
    {TrueClass => 0}
  end
end


# c = EqualTo.new(0, 0)
#
# p c.evaluate


def obzolute(x)
   [GreaterThan.new(0, x), LessThan.new(0, x), EqualTo.new(0,x)].each do |predicate|
      unless predicate.evaluate.nil?
        return predicate.evaluate
      end
   end
end

p obzolute(0)
p obzolute(-1)
p obzolute(2)


Second Version

class Predicate
  def initialize(operator, value)
    @operator, @value = operator, value
  end
 
  def evaluate
    @value.send(@operator.to_sym, 0)
  end
 
  def result
    {'>' => @value, '==' => 0, '<' => -@value}
  end
 
end

p1 = Predicate.new('<', -1)

p (p1.evaluate and p1.result['<'])


p2 = Predicate.new('==', 0)

p (p2.evaluate and p2.result['=='])


p3 = Predicate.new('>', 2)

p (p3.evaluate and p3.result['>'])

MIT Scheme Console

$ ./mit-scheme console
MIT/GNU Scheme running under OS X
Type `^C' (control-C) followed by `H' to obtain information about interrupts.

Copyright (C) 2014 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.

Image saved on Saturday May 17, 2014 at 2:39:25 AM
  Release 9.2 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118 || Edwin 3.116
;Warning: Invalid keyword: "console"
;Warning: Unhandled command line options: ("console")

1 ]=> 486

;Value: 486

1 ]=> (+ 137 349)

;Value: 486

1 ]=> (- 1000 334)

;Value: 666

1 ]=> (* 5 99)

;Value: 495

1 ]=> (/ 10 5)

;Value: 2

1 ]=> (+ 2.7 10)

;Value: 12.7

Combination = (operator operand1 operand2). The value of the combination is computed by applying the operator to the operands.

The prefix notation has the advantage of taking an arbitrary number of arguments. Making it easy to compute your tax deductions:

1 ]=> (+ 21 35 12 7)

;Value: 75

Calculate Mileage rate deduction:

1 ]=> (+ (* 57.5 200) (* 23 700))

;Value: 27600.

57.5 cents for each business mile driven and 23 cents for moving deduction. I drove 200 miles for business miles and 700 miles for moving. So I get a total deduction of $276 (since the answer is in cents).

This shows another advantage of prefix notation where we can have combinations of elements which are combinations.

Defining Variable

1 ]=> define size 2

;Syntactic keyword may not be used as an expression: #[keyword-value-item 13]
;To continue, call RESTART with an option number:
; (RESTART 1) => Return to read-eval-print level 1.

2 error> 
;Unbound variable: size
;To continue, call RESTART with an option number:
; (RESTART 4) => Specify a value to use instead of size.
; (RESTART 3) => Define size to a given value.
; (RESTART 2) => Return to read-eval-print level 2.
; (RESTART 1) => Return to read-eval-print level 1.

3 error> 
;Value: 2

3 error> (define size 2)

;Value: size

3 error> size

;Value: 2

3 error> (* 5 size)

;Value: 10

3 error> (define pi 3.14159)

;Value: pi

3 error> (define radius 10)

;Value: radius

3 error> (* pi (* radius radius))

;Value: 314.159

3 error> (define circumference (* 2 pi radius))

;Value: circumference

3 error> circumference

;Value: 62.8318

Installing Mit Scheme LISP on Mac OS 10.7.5

Hit this URL http://ftp.gnu.org/gnu/mit-scheme/stable.pkg/9.2/mit-scheme-9.2-x86-64.tar.gz on the browser to download the file.

 cd Downloads/
 cd mit-scheme-9.2
 cd src
 ./configure --prefix=/usr/local
 make -j9 compile-microcode
 make install
 cd /usr/local/bin
 ./mit-scheme --version

You should see:

MIT/GNU Scheme microcode 15.3
Copyright (C) 2014 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Image saved on Saturday May 17, 2014 at 2:39:25 AM
  Release 9.2 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118
  Edwin 3.116
Moriturus te saluto.

Saturday, December 12, 2015

Notes for 5 Hidden Gems of the Ruby Standard Library Presentation

Set
- It doesn't keep order
- It doesn't support duplicates
- It's very fast at finding elements


BLACKLISTED_IPS = %w(42.100.119.12 61.103.82.121)

def black_listed?(ip)
  BLACKLISTED_IPS.include?(ip)
end

vs

require 'set'

same code as before

Find the process name using the process id

ps -p 1 -o comm=

/sbin/launchd

-p : PID
-o : command name

In this case the process id is 1 and comm is the command name. The story behind why I had to use this command. MySQL server stopped working on my Mac. It was complaining that the server process had quit without updating the PID file. The PID file did not exist. So I created one and put process id 1 as the value. When I made an attempt to restart the MySQL server, the entire machine rebooted. It turns out that the process with id one is the launchd that starts all other child processes in Mac.

`$ERROR_INFO' not initialized

Delete:

--warnings

in .rspec file.

Friday, December 11, 2015

Neither Pony nor ActionMailer appear to be loaded so email-spec is requiring ActionMailer.

Add require statement for action_mailer before email_spec in spec_helper.rb:

require 'action_mailer'
require "email_spec"

Tuesday, December 08, 2015

Find files that was changed before certain number of days

1. Find all controllers that was changed 4 days ago.

find ./app/controllers -type f -mtime -4

2. Find all views that was changed 4 days ago.

find . -mtime -4 -name "*.haml" -print

Monday, December 07, 2015

How to automatically source ~/.bash_profile in Mac OS

Add the line:

source ~/.bash_profile

to the ~/.bashrc file. Open a new terminal to test whether it works.

Sunday, December 06, 2015

Form vs Structure



Form: The visible shape of something Structure: The arrangement of and relations between the elements of something complex. Form relates to the external shape – best thought of as a silhouette. It is visible. Structure is goes beyond the visible – it is the internal development and relationship between parts. It is about the internal skeleton and organs. Think of it as an X ray or CT scan.

Diagram for 3 Rules for Design Article

Diagrams for Articles





Friday, December 04, 2015

Find all files less than a certain size

find ./app/helpers -type f -size -50c | more

If you want to find files greater than a certain size

find ./app/helpers -type f -size +50c | more

Show All the Commits Behind the Master for a Given Branch in Git

This will prepend "git show" to the commit hash 
git rev-list your-branch-name --not master | sed 's/^/git show /'  | pbcopy

git rev-list rails424 --not master | sed 's/^/git show /'  | xargs git show

will show the diff for each of the commit hash.

Tuesday, December 01, 2015

How to check when a file was deleted in git

1. Check the log for a particular file.

git log -- app/views/articles/publish.html.erb

2. Copy the commit hash and do:

git show commit-hash

You can view the changes made to the files including the files that were deleted.

Monday, November 30, 2015

Sunday, November 29, 2015

Could not find 'railties' (>= 0) among 46 total gems

This happened in a Rails 5 alpha installation. Use:

bundle exec rails -v
bundle exec rails c

to resolve this issue.

Thursday, November 26, 2015

Rails 5 Quickly Book

I am updating my Rails 4.2 Quickly book to Rails 5. If you want to read it online, here are the links:

Chapter 1 : Running the Server
Chapter 2 : Hello Rails
Chapter 3 : Model
Chapter 4 : Model View Controller
Chapter 5 : View to Model
Chapter 6 : Update Article
Chapter 7 : Show Article
Chapter 8 : Delete Article
Chapter 9 : View Duplication
Chapter 10 : Relationships
Chapter 11 : Delete Comment
Chapter 12 : Restricting Operations

For initial setup, checkout this article : Creating a Rails 5 Project

Tuesday, November 24, 2015

JSON::ParserError:

JSON::ParserError:
       757: unexpected token at

Solution:

Escape the double quotes:
"{\"foo\":\"bar\"}"

`class_exec': no block given (LocalJumpError)

This happens in Rspec if you miss the it() method. For example:

describe Car
   expect(Car.speed).to eq(0)
end

The error message is not beginner friendly and can be improved.

Thursday, November 19, 2015

Rename all .css.scss to .scss file

Stolen script to make upgrade to Rails 4.2 easier: Save it as .sh file, run chmod 755 renamer.sh

#! /usr/bin/env bash


for f in $(find . -type f -iname '*.css.scss'); do

renamed=$(echo "${f}" | sed 's/.css.scss$/.scss/g')

cmd="git mv ${f} ${renamed}"

echo $cmd

eval $cmd

done

  

Monday, November 16, 2015

Wait for External calls to finish

Note to myself: Create an utility similar to this : https://robots.thoughtbot.com/automatically-wait-for-ajax-with-capybara to fix the sleep hack in Stripe project.

# spec/support/wait_for_external_call.rb
module WaitForExternalCall
  def wait_for_remote_call
    Timeout.timeout(Capybara.default_wait_time) do
      loop until custom_assertion_passed?
    end
  end

  def custom_assertion_passed?
   
  end
end

RSpec.configure do |config|
  config.include WaitForExternalCall, type: :feature
end

How to set default editor for bundle open

 export BUNDLER_EDITOR='mate'

Sunday, November 15, 2015

Testing Tip

Instead of checking each attribute of a JSON response in your test, you can use json-schema for api validation. Use jsonschema.net to generate a valid JSON schema from a valid sample data. You can delete all the links that point to jsonschema.net and save the json file in the fixtures directory.

Could not find 'railties' (>= 0) among 46 total gem(s) (Gem::LoadError) in Rails 5 Project

Problem

zepho-mac-pro:rails5 zepho$ rails -v
/Users/zepho/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/rubygems/dependency.rb:315:in `to_specs': Could not find 'railties' (>= 0) among 46 total gem(s) (Gem::LoadError)
Checked in 'GEM_PATH=/Users/zepho/.rvm/gems/ruby-2.2.3@r5blog:/Users/zepho/.rvm/gems/ruby-2.2.3@global', execute `gem env` for more information
from /Users/zepho/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/rubygems/dependency.rb:324:in `to_spec'
from /Users/zepho/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/rubygems/core_ext/kernel_gem.rb:64:in `gem'
from /Users/zepho/.rvm/gems/ruby-2.2.3@r5blog/bin/rails:22:in `
'


Fix:

zepho-mac-pro:rails5 zepho$ bundle check
Resolving dependencies...
The Gemfile's dependencies are satisfied
zepho-mac-pro:rails5 zepho$ gem list rails

*** LOCAL GEMS ***

jquery-rails (4.0.5)
rails-deprecated_sanitizer (1.0.3)
rails-dom-testing (1.0.7)
rails-html-sanitizer (1.0.2)
sprockets-rails (2.3.3)
zepho-mac-pro:rails5 zepho$ gem list railties

*** LOCAL GEMS ***


zepho-mac-pro:rails5 zepho$ gem install rails
Fetching: rack-1.6.4.gem (100%)
Successfully installed rack-1.6.4
Fetching: activesupport-4.2.5.gem (100%)
Successfully installed activesupport-4.2.5
Fetching: actionview-4.2.5.gem (100%)
Successfully installed actionview-4.2.5
Fetching: actionpack-4.2.5.gem (100%)
Successfully installed actionpack-4.2.5
Fetching: railties-4.2.5.gem (100%)
Successfully installed railties-4.2.5
Fetching: activejob-4.2.5.gem (100%)
Successfully installed activejob-4.2.5
Fetching: actionmailer-4.2.5.gem (100%)
Successfully installed actionmailer-4.2.5
Fetching: arel-6.0.3.gem (100%)
Successfully installed arel-6.0.3
Fetching: activemodel-4.2.5.gem (100%)
Successfully installed activemodel-4.2.5
Fetching: activerecord-4.2.5.gem (100%)
Successfully installed activerecord-4.2.5
Fetching: rails-4.2.5.gem (100%)
Successfully installed rails-4.2.5
11 gems installed
zepho-mac-pro:rails5 zepho$ rails -v
Rails 5.0.0.alpha

Creating a Rails 5 Project

1. Create a Gemfile

source "https://rubygems.org"

ruby '2.2.3'

gem 'rack', github: 'rack/rack'
gem 'rails', git: 'git://github.com/rails/rails.git'
gem 'arel', git: 'git://github.com/rails/arel.git'

2. bundle

3. bundle exec rails new . --dev --force

4. bundle exec rails s

Go to localhost:3000, you should now see 5.0.0.alpha in the environment.

Reference

Setting up Rails 5 app from edge

Monday, November 09, 2015

ActionController::UnknownHttpMethod:

In Rails 4.x:

In your tests, call process method like this:

 process :some_action, 'OPTIONS'

Sunday, November 08, 2015

Redefining a Private Method in Ruby

class ActiveRecord

  private

  def hi
    'I am private'
  end
end

class ActiveRecord

  def greet
    hi
  end


  private

  def hi
    'I am redining you'
  end

end

a = ActiveRecord.new

p a.greet

Monkey patching (Coding Horror):

class ActiveRecord

  private

  def hi
    'I am private'
  end
end

class MyActiveRecord < ActiveRecord

  def greet
    hi
  end


  private

  def hi
    'I am redefining you'
  end

end

a = MyActiveRecord.new

p a.greet

Unnecessary Complication:

class Client

  def print
    say
  end

  private
 
  def say
    "hello"
  end
end

# Create a subclass of Client
MyClient = Class.new(Client) do
  define_method(:say) do
    "hello from an overridden private method"
  end
end

puts MyClient.superclass

my_client = MyClient.new
puts my_client.print

Simpler Way to Accomplish the Same Thing:

class Client

  def print
    say
  end

  private
 
  def say
    "hello"
  end
end

class MyClient < Client
  def say
    "hello from an overridden private method"
  end
end

puts MyClient.superclass

my_client = MyClient.new
puts my_client.print





Thursday, November 05, 2015

Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true rails 4.2.4

In application.rb, inside the class add:

Rails.application.routes.default_url_options[:host] =  "load url that is appropriate for different environments in your app here"

Now you can go to the rails console:

 > include Rails.application.routes.url_helpers

and call different url_helpers like this:

profile_url



Monday, November 02, 2015