Ruby : Public, Private, Protected simplified

Like many parts of Ruby that look like special language features, Ruby’s privacy key-
words are actually methods. Yes access modifiers are simple method calls, they don’t create a new scope. public, private and protected are really methods, so they can take parameters. If you pass a Symbol to one of them, that method’s visibility is altered.

In this case, they’re methods of Module . When you call private , protected , or public , the current module (remember that a class is just a special kind of module) changes the rules it applies to newly defined methods from
that point on.

Private and protected methods work a little differently in Ruby than in most other
programming languages. Suppose you have a class called Foo and a subclass SubFoo .
In languages like Java, SubFoo has no access to any private methods defined by Foo .
As seen in the Solution, Ruby provides no way to hide a class’s methods from its sub-
classes. In this way, Ruby’s private works like Java’s protected .

Suppose further that you have two instances of the Foo class, A and B. In languages
like Java, A and B can call each other’s private methods. In Ruby, you need to use a
protected method for that. This is the main difference between private and pro-
tected methods in Ruby. Continue reading

Ruby : Writing Very long string in multiple lines

Using backward slash (\) at the end of line tells the ruby parser that the line is still incomplete. Also the parser concatenates the two string into one.

> long_sentence = "This is a very long sentence and this line even cannot"\
> " be written in one line"
 => "This is a very long sentence and this line even cannot be written in one line"

 

Ruby memoization explained

Memoization is a technique you can use to speed up your accessor methods. It caches the results of methods that do time-consuming work, work that only needs to be done once. In Rails, you see memoization used so often that it even included a module that would memoize methods for you.

This is how Memoization works in Ruby

 > var1 ||= 12
 => 12 
 > var1 ||= 13
 => 12

another workaround

 > var2 = var2 || 14
 => 14 
 > var2 = var2 || 16
 => 14 

Something different

 > var2 = var3 || 16
NameError: undefined local variable or method `var3' for main:Object
 from (irb):5
 from /home/john/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
 >
 > var3 = var3 || 16
 => 16

Some real world example

You’ll see this memoization pattern all the time in Ruby:

class User < ActiveRecord::Base
  def twitter_followers
    # assuming twitter_user.followers makes a network call
    @twitter_followers ||= twitter_user.followers
  end
end

The ||= more or less translates to @twitter_followers = @twitter_followers || twitter_user.followers. That means that you’ll only make the network call the first time you call twitter_followers, and future calls will just return the value of the instance variable @twitter_followers.

 

Sources:

I would like to recommend you to read this:

http://www.justinweiss.com/articles/4-simple-memoization-patterns-in-ruby-and-one-gem/

 

Recursive OpenStruct in Ruby with nested Array of Hashes

Hey do you want to have your Hashes with collection/Array of Hashes more object oriented but along with it want it to behave as it was before?. Well you can use my library to do so. I have used the Ruby’s native OStructOStruct Library. RStruct Can be used as your De-Serializer for JSON type data in Postgres.

# This only supports Hashes inside Hashes
class RStruct
  # @author Shiva Bhusal
  # @blog cbabhusal.wordpress.com
  # Recursive OpenStruct
  # #
  def self.new(object)
    if object.is_a?(Hash)
      object = object.clone
      object.each do |key, value|
        object[key] = new(value)
      end
      OpenStruct.new(object)
    else
      object
    end
  end
end

Example:

> a = {l1: {l2: {name: 'shiva', name_is_valid?: true}}}
 => {:l1=>{:l2=>{:name=>"shiva", :name_is_valid?=>true}}}
> aa = RStruct.new(a)
 => #<OpenStruct l1=#<OpenStruct l2=#<OpenStruct name="shiva">>> 
> aa.l1.l2.name
 => "shiva"
> aa.l1.l2.name_is_valid?
 => true

For Arrays of Hashes inside the Hashes

class RStruct
  # @author Shiva Bhusal
  # @blog cbabhusal.wordpress.com
  # Recursive OpenStruct
  # #
  def self.new(object)
    if object.is_a?(Hash)
      object = object.clone
      object.each do |key, value|
        object[key] = new(value)
      end
      OpenStruct.new(object)
    elsif object.is_a?(Array)
      object.map do |item|
        new(item)
      end
    else
      object
    end
  end
end

For usage with Rails’s AController::Parameter

class RStruct
  # @author Shiva Bhusal
  # @blog cbabhusal.wordpress.com
  # Recursive OpenStruct
  # #
  def self.new(object)
    if object.is_a?(Hash)
      object = object.clone
      object.each do |key, value|
        new_value = value.to_hash.with_indifferent_access rescue value
        object[key] = new(new_value)
      end
      OpenStruct.new(object)
    elsif object.is_a?(Array)
      object.map do |item|
        new(item)
      end
    else
      object
    end
  end
end

Usages

> data = {key1: [{sub_key1: 'value1'}]}
 => {:key1=>[{:sub_key1=>"value1"}]}
 > structured_data = RStruct.new(data)
 => #<OpenStruct key1=[#<OpenStruct sub_key1="value1">]>
 > structured_data.key1.first.sub_key1
 => "value1"

 

And if you are trying to re-struct the data from Stripe Objects then you may want to modify the code like

if object.is_a?(Hash)
  object = object.clone
  object.each do |key, value|
    new_value = value.to_h rescue value
    object[key] = new(new_value)
  end
  OpenStruct.new(object)

Making Ruby Gems executable from terminal : Standalone

I presume you have developed a ruby gem. Its working fine when required to another ruby application. Now you want to make it standalone and running from terminal.

Wondering how to do that?

Its preety simple and straight forward way. All stuffs are done by the bundler itself. You just need to configure it properly.

It was different in older bundler version.. but now it works like this

In you_gem.gemspec

# it tells bundler that all executable files are inside `exe` dir
#   see http://bundler.io/blog/2015/03/20/moving-bins-to-exe.html
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }

 

So you need to keep all of your executables inside `exe` folder and sample exe file looks like. the file name is just ‘hulaki‘ with no extension.

#!/usr/bin/env ruby
# encoding: UTF-8
# exe/hulaki

# $: is just a shortcut for $LOAD_PATH. __FILE__ is the relative 
#   path to the script. This adds the current script directory 
#   to the load path
this_file = Pathname.new(__FILE__).realpath
$:.unshift File.expand_path("../../lib", this_file)
require 'hulaki'

Sources:

http://bundler.io/blog/2015/03/20/moving-bins-to-exe.html

http://stackoverflow.com/questions/9238367/ruby-unshift-file-dirname-file