codedecoder

breaking into the unknown…


1 Comment

difference between private protected public in ruby

private, protected and public control the visibility of methods in ruby class .By default methods in ruby are public except global and initialize method which are private by default. As far as variable are concerned they are private by default as variable can’t be seen by them self but through getter and setter method defined for a variable. you can define the getter and setter method yourself, which is not actually needed as it can be achieved by using :attr_accessor. the variables for which you have defined getter and setter methods behave as public. constants are effectively public , there is no way to define a constant that is inaccessible to outside use. we can say that public, private and protected apply only to methods

private, protected and public are not any keyword but actual method of object class that operate on any other class, dynamically altering the visibility of its methods . you can get the list of private, protected or public method of a class by using private_methods , protected_methods and public_methods on it.

private, protected and public take methods name as argument. If you do not pass argument all the method following them will have the same visibility until it is changed by applying the other. Let us illustrate it with examples in visibility_demo.rb files

# this global method defined outside class so private
def iam_global
  puts "Iam global"
end

class VisibilityDemo

  def initialize
    @message = "Iam the class demonstrating visibility in ruby"
  end
  # No visibility specifier given so public by default

  def pub_method
    puts "Iam public"
  end

  private
  # This method appears after the private' visibility specifier so private
  def pri_method
    puts "Iam private"
  end

  # This method is also private because the previous visibility not overridden
  # specifier has not been overridden
  def pri_method2
    puts "Iam private"
  end

  protected
  # This method appears after the protected visibility specifier so protected
  def pro_method
    puts "Iam protected"
  end

  public
  #this method overridden above protected specifier and become public
  def pub_method2
    puts "Iam public"
  end
end

The risk in above way of defining the visibility (visibility specifier without arguments) is that all following method will have same behaviour(try by changing the position of say private, keep it at top), which we not always want, so it is better to use them in argument form if the list of particular visibility is not very long. Let us redefine it in argument form and also add some other piece of code, needed to demo visibility behaviour.

def iam_global
  puts "Iam global"
end

class VisibilityDemo

  def initialize
    @message = "Iam the class demonstrating visibility in ruby"
  end

  def pub_method
    puts "#{self}"
    puts "Iam public"
  end

  def pri_method
    puts "Iam private"
  end

  def pri_method2
    puts "Iam private"
  end

  def pro_method
    puts "Iam protected"
  end

  def demo_explicit_object_calling_pro(obj)
    #call the protected method on explcit object
    obj.pro_method
  end

  def pub_method2
    puts "Iam public"
  end

  #specifying visibility specifier with argument
  private :pri_method, :pri_method2
  protected :pro_method
end

#class inheriting from VisibilityDemo class
class InheritVisibility < VisibilityDemo
  # the will call methods of parent class with self as explicit receiver
  def call_methods_with_self
    self.pub_method
    self.pro_method
    self.pri_method
  end

  # the will call methods of parent class without any receiver
  def call_methods_without_receiver
    pub_method
    pro_method
    pri_method
  end

  #overriding private method of parent class
  def pri_method2
   puts "I have overrided parent and become public"
  end

end

#class not inheriting from VisibilityDemo
class AnyClass
  def call_methods
    pub_method
    pro_method
    pri_method
  end  
end

Now let us list all the types of method on irb console
> load “/home/arun/Desktop/visibility_demo.rb” #load the visibility_demo.rb file
=> true
> @visbiility_demo = VisibilityDemo.new # create instance of VisibilityDemo class
=> #
> @visbiility_demo.public_methods # list the public methods
=> [:pub_method, :pub_method2,...]
> @visbiility_demo.protected_methods # list the protected methods
=> [:pro_method]
> @visbiility_demo.private_methods  # list the private methods
=> [:initialize, :pri_method, :pri_method2, :iam_global, ..] # see that initialize and iam_global listed under private

O.K, so we now know how to set the visibility of a method. Let us now see how the visibility specifier change the behaviour of methods in its own class and its inherited classes.

NOTE : before you proceed you must be clear on self and implicit and explicit receiver of a method . You should also know that, there is three way of calling any method : method_name , self.method_name, @object.method_name

1 => irrespective of its visibility any method can be called only in its class hierarchy

See the below output on irb :

> @any_class = AnyClass.new # create instance of any class
 => #<AnyClass:0x942b25c>
> @any_class.pub_method # call the pub method of VisibilityDemo class
NoMethodError: undefined method `pub_method’ for #<AnyClass:0x942b25c> #give error , can’t be called
> @any_class.pro_method # call the protected method of VisibilityDemo class
NoMethodError: undefined method `pro_method’ for #<AnyClass:0x942b25c> #give error , can’t be called
> @any_class.pri_method # call the private method of VisibilityDemo class
NoMethodError: undefined method `pri_method’ for #<AnyClass:0x942b25c> #give error , can’t be called
> @any_class.call_methods # call method of AnyClass calling VisibilityDemo class method implicitly
NoMethodError: undefined method `pub_method’ for #<AnyClass:0x942b25c>

2 => Public method can be called on any object in the class hierarchy as the explicit receiver, but protected and private can’t

See the below output on the irb console :

> self
=> main
> @visbility_demo = VisibilityDemo.new # creating object of  VisibilityDemo class
 => #<VisibilityDemo:0x970c214 @message=”Iam the class demonstrating visibility in ruby”>
> @visbility_demo.pub_method #call the public method
Iam public
> @visbility_demo.pro_method #call the protected method
NoMethodError: protected method `pro_method’ called for #<VisibilityDemo:0x970c214> # give error
> @visbility_demo.pri_method #call the private method
NoMethodError: private method `pri_method’ called for #<VisibilityDemo:0x970c214> # give error

NOTE : Here there is one exception for protected method, protected method can also be called on a object if its belongs to the same class as self.

In the above output , you are running the code from irb and so at this point of program self is main, but the object @visbility_demo belongs to VisibilityDemo class, since the class of self and the class of object is different, the protected method throw error. See the below output where protected method called on explicit object and worked fine.

> @visbiility_demo = VisibilityDemo.new # creating object of VisibilityDemo
 => #<VisibilityDemo:0x955e034 @message=”Iam the class demonstrating visibility in ruby”>
> obj = VisibilityDemo.new # creating another object of VisibilityDemo
 => #<VisibilityDemo:0×9531408 @message=”Iam the class demonstrating visibility in ruby”>
> @visbiility_demo.demo_explicit_object_calling_proc(obj) #for demo_explicit_object_calling_proc method self is VisibilityDemo and since object passed to it is also of same class, the protected method worked this time
Iam protected

3 => Public and Protected both can be called with self as explicit receiver but Private can’t

See the below output on the irb console

> @inherting_visibility = InheritVisibility.new # create instance of the inheriting class
 => #<InheritVisibility:0x96e068c @message=”Iam the class demonstrating visibility in ruby”>
> @inherting_visibility.call_methods_with_self # call the method calling parent class method with self
Iam public # public method called successfully with self
Iam protected # protected method called successfully with self
NoMethodError: private method `pri_method’ called for #<InheritVisibility:0x96e068c> # private method give error

4 => public protected and private all can be called implicitly i,e without any receiver

See the below output on irb console:

> @inherting_visibility = InheritVisibility.new
 => #<InheritVisibility:0x96e068c @message=”Iam the class demonstrating visibility in ruby”>
> @inherting_visibility.call_methods_without_receiver
Iam public
Iam protected
Iam private

5 => If a private method overridden in its subclass, the method exhibit visibility as defined in subclass

see the below output in irb console

> @visibility_demo = VisibilityDemo.new # create object of VisibilityDemo class
 => #<VisibilityDemo:0x9e49734 @message=”Iam the class demonstrating visibility in ruby”>
> @visibility_demo.pri_method2 # call the private method
NoMethodError: private method `pri_method2′ called for #<VisibilityDemo:0x9e49734> # error as expected
> @inherit_visibility = InheritVisibility.new # create object of subclass of VisibilityDemo class which override the method
 => #<InheritVisibility:0x9f01e4c @message=”Iam the class demonstrating visibility in ruby”>
> @inherit_visibility.pri_method2 # call the private method of parent again
I have overrided parent and become public # it worked this time as it is overridden in the subclass 

So, from the above points we can summarized the behaviour as below :

Private method can be called only implicitly (i,e without any receiver) . Protected method can be called with a explicit receiver but that should be self or if a object, the object must belong to same class as self . Public method can be called in any way in its class hierarchy .

So through above point ruby ensure that private method should never we called on a object and let ruby invoke it by its own. Remember that you can create instance of any class anywhere and if a highly secure method say which manipulate user balance, call it current_account_balance is not private, then any person can misuse it by creating the object of class and calling the method.

Here, ruby differ in private implementation in C and c++ . In C ++  “private” means “private to this class”, while in Ruby it means “private to this instance”. What this means, in C++ from code in class A, you can access any private method for any other object of type A. In Ruby, you can not: you can only access private methods for your instance of object, and not for any other object instance (of class A).

It should be also noted that, ruby prevent accidental misuse of private method, but not prevent it strictly. So if you want, you can invoke a private method on an object also with send, see the below output on console

> @visibility_demo = VisibilityDemo.new
 => #<VisibilityDemo:0x9e8c804 @message=”Iam the class demonstrating visibility in ruby”>
> @visibility_demo.pri_method # trying to call the private method on object
NoMethodError: private method `pri_method’ called for #<VisibilityDemo:0x9e8c804> #throw no method error
> @visibility_demo.send(:pri_method) # # trying to call the private method on object with send
Iam private #it worked

Since, private method can’t be called on its own object also, but there are some cases where we me need it, so there we can make the method protected. Let us take a simple example below in file say my_bank.rb

class BankRate

  def initialize(bank_name, rate)  
    @bank_name = bank_name
    @rate      = rate  
  end 

  def bank_name
     @bank_name
  end 

  def current_rate  
    @rate  
  end 

  def comparative_rate(bank)  
    if bank.current_rate > current_rate  
      "#{bank.bank_name} have higher rate then #{@bank_name}"  
    else  
      "#{bank.bank_name} have higher rate then #{@bank_name}"  
    end  
  end 

  private :current_rate  
end  

# call the comprative_rate method
@sbi = BankRate.new("sbi", 12)  # first object of BankRate class
@icici = BankRate.new("icici", 14)  # secone object of same BankRate class
puts  @sbi.comparative_rate(@icici) # calling comprative_rate method on first object and passing second as argument

So, we have a BankRate class dealing with bank rate. We want that, the current_rate should not be misused so we have made it private. This class also have a method which compare the rate of the bank with another bank . Try to load the my_bank.rb file on console

> load “/home/arun/Desktop/my_bank.rb” #load my_bank.rb file
NoMethodError: private method `current_rate’ called for #<BankRate:0x9f90d90 @bank_name=”icici”, @rate=14>

So you can see that, although the @sbi  and @icici bot are object of the same class, still they can’t invoke the private method. Now change the visibility of current_method to protected in above file i,e protected :current_rate and run it again.

> load “/home/arun/Desktop/visibility_demo.rb” #load my_bank.rb file again
icici have higher rate then sbi # it worked this time

So, this worked this time. This demonstrate when to use private and when to use protected.

Reference :

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes

http://lylejohnson.name/blog/2003/12/09/private-methods-in-c-and-ruby/ # comparison with c, c++


Leave a comment

multiple project using sidekiq on same machine

In this post I have explained how to install , configure, start and stop sidekiq . You can start sidekiq from terminal with below command on your project root

$ bundle exec sidekiq -e staging -d -L log/sidekiq.log # -e option set the environment (staging in this case), -d option make the sidekiq to start as daemon i,e it will keep running even after you close the terminal, -L option set the log file path, you can get the list of all available option with -h as below

$ sidekiq -h
-c, –concurrency INT                           processor threads to use
-d, –daemon                                           Daemonize process
-e, –environment ENV                          Application environment
-g, –tag TAG                                            Process tag for procline
-i, –index INT                                         unique process index on this machine
-p, –profile                                              Profile all code run by Sidekiq
-q, –queue QUEUE[,WEIGHT]…       Queues to process with optional weights
-r, –require [PATH|DIR]                     Location of Rails application with workers or file to require
-t, –timeout NUM                                  Shutdown timeout
-v, –verbose                                            Print more verbose output
-C, –config PATH                                  path to YAML config file
-L, –logfile PATH                                 path to writable logfile
-P, –pidfile PATH                                 path to pidfile
-V, –version                                           Print version and exit
-h, –help                                                 Show help

O.K , so we know how to start sidekiq with all the possible option. But what happen if you start the sidekiq on two or more project on the same machine. In my case, My staging server host two projects, and all of them need sidekiq as background worker, so I moved to project folder and started sidekiq on both

ThirdPillar]# bundle exec sidekiq -e staging -d -L log/sidekiq.log
Barcelona]# bundle exec sidekiq -e staging -d -L log/sidekiq.log

Now I checked the running instance of sidekiq

ps -ef | grep sidekiq
root      3823     1  1 03:03 ?  00:00:38 sidekiq 2.12.0 ThirdPillar [0 of 25 busy]
root      4116     1  1 03:04 ?  00:00:35 sidekiq 2.12.0 Barcelona [0 of 25 busy]

So, I can see that, sidekiq have started on both the project and running on different port. But when I tried to load my application, all the pages which involve background processing start breaking. So the sidekiq not working . If I kill one sidekiq, the other start working. It is obvious that, the multiple sidekiq daemon conflicting with each other.

Now understand why is the conflict :

=> sidekiq work on redis as database server. basically it store the background processes on redis

=> One machine can have only single redis server, but redis can have multiple database on it

=> Unless you provide separate redis configuration for sidekiq, it will work with default i,e try to use redis on the local machine itself and the  database number 0 on it

So the problem is that, both sidekiq instance you have started, using the same redis server and the database number 0, so causing the conflict and none of them working. So now we have two solutions:

solution 1: configure sidekiq to point to different redis server

solution 2: configure sidekiq to use the same redis server available locally, but make them to use different database and also separate them with namespace

We will go for solution 2 . Let us try something with redis on console before changing sidekiq configuration.

> Redis.new # no options is passed
=> #<Redis client v3.0.4 for redis://127.0.0.1:6379/0> # o number database being used
> Redis.new(db: 1) # database 1 is paased
=> #<Redis client v3.0.4 for redis://127.0.0.1:6379/1> # 1 number database being used
> Redis.new(db: 4)
=> #<Redis client v3.0.4 for redis://127.0.0.1:6379/4> 4 number database being used

Here, you can see that, your redis server is running at 127.0.0.1:6379 and number after / is the database number

So now we can introduce below line in config/initializer/sidekiq.rb file of both the project

config.redis = { :namespace => ‘ThirdPillar’, :url => ‘redis://127.0.0.1:6379/0′ }

config.redis = { :namespace => ‘Barcelona’, :url => ‘redis://127.0.0.1:6379/1′ }

The namespace can have any value, but as convention I have keep the name same as the folder name of the project. So the Barcelona will use datbase 1 of the redis server at redis://127.0.0.1:6379 . The modified configuration files for Barcelona look as below.

config/initializer/sidekiq.rb

require 'sidekiq'
require 'sidekiq-status'

Sidekiq.configure_client do |config|
  config.client_middleware do |chain|
    chain.add Sidekiq::Status::ClientMiddleware
  end
  config.redis = { :namespace => 'Barcelona', :url => 'redis://127.0.0.1:6379/1' }
end

Sidekiq.configure_server do |config|
  config.server_middleware do |chain|
    chain.add Sidekiq::Status::ServerMiddleware, expiration: 30.minutes # default
  end
  config.redis = { :namespace => 'Barcelona', :url => 'redis://127.0.0.1:6379/1' }
end

Make similar change in sidekiq.rb of the other project. Restart the sidekiq on both the project, both will strat working  :)

Reference:
https://github.com/mperham/sidekiq/wiki/Advanced-Options

http://rubydoc.info/gems/sidekiq/Sidekiq

http://redis.io/topics/quickstart


Leave a comment

ruby

This post will contain link to all the post I have written within ruby category . I find lack of this support in wordpress. when you click any link within a category(say ruby), it open up all the post on single page, and you have to scroll down a lot to find a particular topic. Ideally it should have just provided links to the post within a particular category. Since it is not doing that, I have made a index file for all the categories.

Below are my post on ruby :

self receiver and ancestorarguments in rubymethods in ruby ,

difference between private protected public in ruby , ruby block : difference between yield &block ,

proc and lambda , require and load , attr_reader attr_writer attr_accessor in ruby ,

exception handling in ruby rails


Leave a comment

arguments in ruby

In this post we will look into arguments in ruby. arguments are the values a method expecting when the method is called. The number of values to be passed and its type is fixed at the time of method definition and is called parameter list.

Parameter : They are variables associated with method at the time of defining it. It decides the number of values and its type which need to be passed at the time a method is called. Each parameter name must be unique in the parameter list.Parameters are positional: they describe the argument in the corresponding position of the argument list. The correspondence isn’t one‐to‐one, as we will see below, but each parameter consumes as many arguments as it can, leaving those that remain for the following parameters.

Arguments : The values passed to the method when it is called. They need to be passed according to the parameter list

To discuss various type of arguments, let create argument_demo.rb file and call different methods in the ruby console.

class ArgumentDemo
  # in ruby argument are passed by reference rather then value
  def demo_pass_by_referance(ref_var)
    substituted_val = ref_var.gsub!("a", "1")
    puts substituted_val
  end

  # in ruby you do not need to define the type of parameter 
  # i,e int, string etc.it get defined dynamically by ruby based 
  # on the passed value at time of method call
  # NOTE: ruby is a dynamically typed language

  def i_need_required_argument(house, street, city, post)
    puts "I exactly need 4 arguments"
  end

  #default value is provided in the start
  def start_with_default(house =12, street ="gandhi road", city, post)
    puts "house => #{house} ,street => #{street}, city => #{city}, post => #{post}"
  end

  # default value is provided at the end
  def end_with_default(house, street, city = "UP", post = 122341)
    puts "house => #{house}, street => #{street}, city => #{city}, post => #{post}"
  end

  # method with any number of arguments
  def variable_arguments(*args)
    args.each do |arg|
      puts arg
    end
  end

  # argument as key => value pair
  def named_arguments(args = {})
    puts args[:house]
    puts args[:street]
  end

  # method supporting block argument
  def block_arguments(any_value)
    if block_given?
      yield
    else
      raise "You must pass a block"
    end
  end

end

Let us load the above file on irb and try out calling different methods with different type of argument

$irb #open irb
> load “/home/arun/Desktop/argument_demo.rb” #load the file
true

Before we read about different types of argument, we should understand that in ruby the arguments are always passed by reference not the value. It means that if the argument get modified by the method, its actual value also get modified. See the below output on the console

> my_name = “arun” 
=> “arun”
> @argumnets = ArgumentDemo.new
=> #<ArgumentDemo:0x9b15400>
> @argumnets.demo_pass_by_referance(my_name)
1run
1.9.3p194 :011 > my_name
=> “1run”

So you can see that you have set the variable my_name with value arun. You passed the my_name variable as a argument to method demo_pass_by_referance, which modify the variable my_name inside it. But when you go outside the method and again try to see the value of my name, you see that now my_name is containing the modified value. This show that, here the my_name is not containing value arun but a reference to this value, so any modification on my_name actually change the referred value.

NOTE  : never modify any variable passed as argument to any method directly, specially if it is also passed to other method . I can give a real case example in terms of params. params in rails store all the values passed with a request to a controller and is accessible throughout the controllers and used to pass as argument to many of the controller methods. Once I did the above things i,e params[:auth_token].gsub!(“_”, “-”) in one of my method and it break the whole authentication system of  my application as the above line corrupt the token which is referenced by many other methods. So whenever you want to modify any argument in a method perform the action on duplicate copy of the argument i,e using dup. So using params[:auth_token].dup.gsub!(“_”, “-”) will not change the referenced value as the operation is performed on the copy of argument.

With the above discussion, Now ,We will experiment with arguments by calling different methods in above file on irb console.

1 => Required Argument :

  1. These are the argument which must be passed when the method is called
  2. passing lesser number of argument as defined in parameter list will throw argument error
  3. nil and false are as valid an argument as any other. If a method requires an argument and nil is supplied in its place, Ruby will not complain. Methods wishing to prohibit such values must do so themselves.

See the below output on irb console

> @arg_demo = ArgumentDemo.new
=> #<ArgumentDemo:0xa276320>
> @arg_demo.i_need_required_argument(12, “chandni chowk”, “Delhi”, 11106)
I exactly need 4 arguments
> @arg_demo.i_need_required_argument(12, “chandni chowk”, “Delhi”)
ArgumentError: wrong number of arguments (3 for 4)
> @arg_demo.i_need_required_argument(12, “chandni chowk”, false, nil)
I exactly need 4 arguments

2 => Optional Argument

  1. If the parameter are given default value, it become optional i,e the method will not complain if the corresponding argument is not passed.Say if a method have 4 parameter and 2 are given default value then argument error will occur if you pass less then or more then 2 argument.
  2. If default value is passed to parameters,  all the default value should be either from start or towards the end. if you put the default value in between, it will give syntax error when the file is loaded or compiled
  3. If no of passed argument is equal to the no of parameter, all the default values will be overridden.
  4. When default parameters are defined towards the end, the passed arguments are assigned to them following the know convention i,e left to right, say the method have 4 parameters in which last two have default value and you pass 3 argument, then these argument is set to first 3 i,e default value of 3rd will be overridden and only the 4th parameter will have the default value
  5. When you set the default parameter at the beginning, it create confusion in assignment of argument to them as far as I have understand.This is how they are getting assigned. Non default parameter are assigned right to left, the remaining arguments are now assigned to the default parameter from left to right as usual.

Below output can illustrate the above points

> @argumnets = ArgumentDemo.new
=> #<ArgumentDemo:0x8988a70>
> @argumnets.start_with_default(“UP”,”2342″) # two argument passed
house => 12 ,street => gandhi road, city => UP, post => 2342  #assigned to the last two non default parameter

> @argumnets.start_with_default(“my street”,”UP”,”2342″) # 3 argument passed
house => my street ,street => gandhi road, city => UP, post => 2342 # last 2 i,e “UP”,”2342″ assigned to city and post following right to left rule and the remaining one i,e “my street” is assigned to the first parameter house following left to right rule

> @argumnets.start_with_default(32,”my street”,”UP”,”2342″) # 4 argument passed so assigned as usual following left to right rule , infact if no of passed argument is equal to the number of parameter bot rule i,e left to right or right to left will give same result
house => 32 ,street => my street, city => UP, post => 2342

> @argumnets.end_with_default(32, “my_street”) # 2 argument passed
house => 32, street => my_street, city => UP, post => 122341 # first two are assigned following left to right rule

> @argumnets.end_with_default(32, “my_street”, “Patna”) # 3 argument are passed
house => 32, street => my_street, city => Patna, post => 122341 # first 3 are assigned following left to right rule

> @argumnets.end_with_default(32, “my_street”, “Patna”, “5643″) # 4 argument are passed
house => 32, street => my_street, city => Patna, post => 5643 # first 4 are assigned following left to right rule

NOTE : Always keep the parameter with default value towards the end

3 => Variable list Arguments

  1. They are created by defining single parameter preceded by * . They are also known as spat arguments
  2. Any number of arguments can be passed separated by comma
  3. In the method they are available as an array

Below output can illustrate the above point.

> @argumnets = ArgumentDemo.new
=> #<ArgumentDemo:0x89d1784>
> @argumnets.variable_arguments(1, “arun”, 3)
1
arun
3
> @argumnets.variable_arguments(1, “arun”, 3, “kapil”)
1
arun
3
kapil
>

4 => Named Arguments

  1. They are defined as a hash with argument being passed as key => value pair
  2. The advantage is that These arguments are not positional thus you do not need to remember to pass a particular value at particular position.
  3. It support variable list argument i,e you can pass any number of arguments.
  4. Disadvantage is that it do not give argument error if user pass no or wrong number of argument. It has to be handle by you in the code.

1.9.3p194 :048 > @argumnets = ArgumentDemo.new
=> #<ArgumentDemo:0x8a44018>
1.9.3p194 :050 > @argumnets.named_arguments({:house =>12, :street => “xyz street”})
12
xyz street

5 => Block Arguments

  1. They are defined by putting & before the parameter name . It has to defined after defining all other parameters including the default one
  2. While calling the method, you should pass the block argument after closing parenthesis of the arguments i,e method(arg1, arg2..){}
  3. They do not contributes to argument count , so No argument error is thrown. You can check it with block_given? method and raise exception to user for passing the block
  4. Block arguments are used in method with yield keyword . read more about block in this post.

> @argumnets = ArgumentDemo.new
=> #<ArgumentDemo:0x8a5e6ac>
1.9.3p194 :066 > @argumnets.block_arguments()
ArgumentError: wrong number of arguments (0 for 1)
> @argumnets.block_arguments(232){puts “Iam passed as a block”}
Iam passed as a block
> @argumnets.block_arguments(232)
RuntimeError: You must pass a block

=> Arity
The arity of a method is the number of arguments it takes. If the method expects a fixed number of arguments, this number is its arity. If the method expects a variable number of arguments, its arity is the additive inverse of its parameter count. Methods implemented in C, i.e. most core methods, have an arity of -1 if they accept a variable number of parameters. It follows, then, that an arity ≥ 0 indicates a fixed number of parameters; a negative value, a variable number. Method and Proc objects have #arity methods which return the arity for the method/proc it objectifies.

Classification by Arity

Methods with fixed arities can be classified as follows: A unary method expects exactly one operand (its receiver), a binary method requires two (its receiver and one argument), ternary-method requires exactly three (its receiver and two arguments), an n-ary method requires n operands (its receiver, and n-1 arguments).


2 Comments

methods in ruby

A method can be define as below:

A method is a named block of parameterized code associated with one or more objects.

ruby supports different type of methods, exhibiting different behaviour in terms of its invocation and visibility. before we look into different types of methods. let us write some methods and see how they behave. create a file method_demo.rb . We will execute these method in irb and keep defining the method type along with it.

NOTE : before you proceed, I assume that you know about self , receiver , ancestor chain and method lookup. If not, it doesn’t make much difference, but knowing them help to understand the concept in better way, so read out it here .

# global method
def iam_global_method
  puts "Iam defined outside class or module at top of the file"
end

# class to demo different methods in ruby
class MethodDemo

  def iam_instance_method
    puts "I can be exicuted only on object of my class"
  end

  def self.iam_class_method
    puts "I can be exicuted on my class, not on its object"
  end

  def demo_explicit_return
    @name = "Arun"
    return "santosh", "kapil"
    puts "I want to get exicuted"
    @name
  end

  def demo_implicit_return
    @name = "Arun"
    puts "I want to get exicuted"
    @name
  end

  def i_will_be_aliased
    puts "you can create aliase of any method"
  end

  def aliase_method
    puts "Iam synonym of my aliase. old method can be called by my name"
  end

  alias :aliase_method :i_will_be_aliased

end

# class inheriting the above class
class SubMethod < MethodDemo
  def global_method_in_subclass
    iam_global_method
  end
end

#any class, not inheriting above classes
class AnyMethod
  def global_method_anyclass
    iam_global_method
  end
end

#it will demonstrate use of alias method
class String
  alias :old_to_i :to_i
  def to_i
    raise "No digits found" unless match(/\d/)
    old_to_i
  end
end

#object or instance singleton method
@method_demo_singleton = MethodDemo.new

#defining singleton method on object
def @method_demo_singleton.only
  puts "only method is availabe only to object @method_demo_singleton"
end

We will call these method on irb and see how they behaves .

$irb # will open the irb console
> load “/home/arun/Desktop/self.demo.rb” # will load the code of method_demo.rb file . read more about load and require in ruby
true # it means your file is loaded successful on the irb console

1 => Global method :

  1. Global methods are defined at top context of a file i,e outside the class or module at the top
  2. Global methods belongs to main:object
  3. Global methods are private method of the main object and so can be accessed privately in all the classes inheriting from it.The ruby object hierarchy is  :  basic_object -> object (global method belongs to it) -> object of custom class A -> class B … so on. So you can conclude that global method is accessible in all the object in your application, but privately i,e without a explicit receiver
  4. Global method visibility is private but accessible through out the application

 

The above points can be illustrated with below output :

> iam_global_method #calling global method with implicit receiver
Iam defined outside class or module at top of the file
> self.iam_global_method # calling with self as receiver
NoMethodError: private method `iam_global_method’ called for main:Object # error thrown
>@subm = SubMethod.new #creating object of Sub class
=> #<SubMethod:0xa00c030>
>@subm.global_method_in_subclass #calling the global method on the subclass object
Iam defined outside class or module at top of the file
> @anym = AnyMethod.new # object of class outside inheritance chain
=> #<AnyMethod:0xa00dc50>
  > @anym.global_method_anyclass # calling the method on object outside class hierarchy
Iam defined outside class or module at top of the file

2 => Instance methods :

  1. defined within a class with def keyword
  2. can be called only on instance i,e object of class within which it is defined or object of the inherited class
  3. can’t we called on class as its receiver

 

The above points can be illustrated with below output :

@method_demo = MethodDemo.new
=> #<MethodDemo:0xa015d4c>
>@method_demo.iam_instance_method
I can be exicuted only on object of my class
> MethodDemo.iam_instance_method
NoMethodError: undefined method `iam_instance_method’ for MethodDemo:Class

3 => Class methods :

  1. defined with self keyword
  2. the class method is singleton to its class i,e associated with class not to its instance
  3. it can be called with the class name in which it is defined
  4. can’t be invoked on object of the class

 

The above points can be illustrated with below output :

> MethodDemo.iam_class_method # calling the method on calss name
I can be exicuted on my class, not on its object
> @method_demo = MethodDemo.new
=> #<MethodDemo:0x9571ecc>
> @method_demo.iam_class_method # calling the method on object of class MethodDemo
NoMethodError: undefined method `iam_class_method’ for #<MethodDemo:0x9571ecc>

4 => Alias method :

  1. alias methods are created with alias or alias_method keyword. both behave same , but differ internally in terms of interpretation of method name. when we write alias :new :old (see there is no comma between the two method name), alias treat new and old as function name. similarly alias_method :new, :old (here comma between the two name) treat new and old as method name. But you can also write alias_method in another way alias_method new, old . In this case new and old are not method name, but variables name which contain the name of the method to be aliased. Thus this allow you to do the aliasing dynamically i,e you can store any name in new and old.
  2. The syntax is alias :new_name :current_name (no comma between literals) , alias_method :new_name, :current_name (comma between literal), alias_method new_name, current_name (new_name, current_name are variables)
  3. alias methods are synonymous to each other. see that both the aliased method i_will_be_aliased and aliase_method return the same output as the old method. basically, Aliases are often used to provide synonyms for method names. For instance, :size may be aliased to :length. This allows the programmer to use method names which “read” more naturally in a given context
  4.  Aliasing is also used to create a method which wraps the method of the same name by performing its own computations then calling the original method. We have seen this in the output of to_i above. the to_i method of string return 0 if the string is not a number. We have reopen the string class and redefined to_i method to raise exception if the string do not contain any number and perform the usual task if pass the test.
  5. In alias :new_name :current_name , the current_name function must be already defined. If the new_name function is already defined, it will be overwritten. NOTE : the new_name function will behave as current_name function at the time of aliasing, even if the current_name function is modified subsequently. for example after opening the string class, we have modified the original to_i function, but since before that we have aliased it to name old_to_i, this will always exhibit the original behaviour of to_i

 

The above points can be illustrated with below output :

> @method_demo = MethodDemo.new
=> #<MethodDemo:0x9665b08>
> @method_demo.i_will_be_aliased #calling the original method
you can create aliase of any method
> @method_demo.aliase_method # calling the old method with the new name
you can create aliase of any method # output is of the original class, the aliased method always point to original method even when the original get modified along the running program
> “arun”.to_i # calling to_i on arun string we have overridden in the String class
RuntimeError: No digits found # we have redefined the to_i method of ruby String class, so it is giving output as per its new defination
> “arun2″.to_i # since now the sring contain a number 2, it is giving 0 as expected
=> 0
> “arun”.old_to_i # we have aliased old_to_i to to_i, so the old_to_i method still point to the original to_i method, so not raising exception even when the string do not contain any number
=> 0

5 => Instance Singleton method

  1. it is associated with a single object of a class and can be called only on it. Any other object will throw nNoMethodError
  2. it is defined with syntex def @object_name.method_name

 

The above points can be illustrated with below output :

> @method_demo_singleton.only #calling the only method on object @method_demo_singleton
only method is availabe only to object @method_demo_singleton
> @method_demo = MethodDemo.new # creating new object of class MethodDemo
=> #<MethodDemo:0x96de530>
> @method_demo.only
NoMethodError: undefined method `only’ for #<MethodDemo:0x96de530> # error thrown as the method is singleton to @method_demo_singleton object not any other object of MethodDemo class.

6 => Return in method :

  1. return is used to pass back the control to the caller at the point is called irrespective of the fact that the whole code is executed or not
  2. explicit call of return cause the program to terminate prematurely . see that “I want to get exicuted” not called in explict use of return
  3. return can cause one or more value to return, in case of more then one value, it is returned as a array
  4. If no return is used, implicitly the value of last executed line is returned

 

The above points can be illustrated with below output :

> @method_demo = MethodDemo.new
=> #<MethodDemo:0x96f3070>
> @method_demo.demo_implicit_return
I want to get exicuted
=> “Arun”
> @method_demo.demo_explicit_return
=> ["santosh", "kapil"]


Leave a comment

self receiver and ancestor in ruby

1 => receiver :

In simple word receiver are object on which you call a method. syntactically, the object before the . operator are receiver

Example :

@user.full_name

self.full_name

here we are calling the method full_name on @user and self, so @user and self are receiver here. They are called explicit receiver as we have specifically called the method on them. But when we call any method without . operator , ruby decide the receiver itself using self and that is called implicit receiver .

2 => ancestor chain :

When ever a method is called, it try to find the method in the receiver(current object). If it is not find there, it try to find it in its parent, if again not found there, it move up to the next parent and keep doing till the last parent(this is called method lookup). Thus the class hierarchy from bottom to up where a method is searched is called ancestor chain.

NOTE : a object contain its own variable but not its own methods. It just contain reference to methods

3 => self :

As discussed above, whenever we call a method, ruby do method lookup in the ancestor chain. Now when method is found, it try to execute it on current object. The ruby decide the current object from self irrespective of whether method is called on implicit or explicit receiver. See what happen when we call method full name with explicit receiver @user

@user.full_name

  1. switch self to receiver (@user)
  2. look up method (full_name) in self’s class (objects do not store methods, only classes can)
  3. invoke method (full_name)

So we can conclude below about self

  • In Ruby, self is a special variable(not a object) that always references the current object.
  • self (current object) is the default receiver of method calls. This means that if We call a method and don’t give an explicit receiver (We don’t put something before the dot) then Ruby will always look into the object referenced by self for that method.
  • self (current object) is where instance variables are found. This means that if We write @name then it’s going to go and look into the object referenced by self for that particular instance variable. It’s to be noted that instance variables are not defined by a class, they are unrelated to sub-classing and the inheritance mechanism.
  • At any point of a running program there will be one and only one self i,e current object referenced by it

Let us see, what self represent at any point of a running program. create a self_demo.rb file as below

puts "self at global level i,e above class defination => #{self}"
class A
  puts "self at just after entering class A => #{self}"
  module M
    puts "self at just after entering module M => #{self}"
    module N
      puts "self at just after entering module N => #{self}"
      class B
        puts "self at just after entering class B in module N => #{self}"
        def method_b
          puts "self in method_b of class B => #{self}"
        end
      end
      puts "self just after existing class B => #{self}"
    end
    puts "self just after existing module M => #{self}"
  end
  puts "self just befor end of class A => #{self}"
end

puts "Calling the method_b"
@obj = A::M::N::B.new
@obj.method_b

puts "demo of self in singleton method"

def @obj.singleton_m
puts "self inside a singleton method of object of class B => #{self}"
end

@obj.singleton_m

run the above file on console with ruby to see the output of above program

$ ruby self_demo.rb
self at global level i,e above class defination => main
self at just after entering class A => A
self at just after entering module M => A::M
self at just after entering module N => A::M::N
self at just after entering class B in module N => A::M::N::B
self just after existing class B => A::M::N
self just after existing module M => A::M
self just befor end of class A => A
Calling the method_b
self in method_b of class B => #<A::M::N::B:0x819cab4>
demo of self in singleton method
self inside a singleton method of object of class B => #<A::M::N::B:0x819cab4>

I have bolded the self in the output.So you can see that self keep changing to current object at any point of the running program.

NOTE : method always execute on current object referenced by self


Leave a comment

rails custom deliver method : sending email through API

I have explained sending email using ActionMailer class of Rails Framework in this post . Go through it first if you not clear on how rail deliver the email. Now our requirement here is that, we do not want the rail to deliver the email for us, But want to get it deliver through ThirdParty email service, which say provide designed templates for the email or advertisement on the email or some other benefits. Basically, we want the email to be delivered through some API rather then Rails. So we need custom email delivery method

Here, you need to understand below two things how action mailer work.

=> ActionMailer create a email object which contain evrything you see in any email : subject, to, from, body, header etc

=> deliver method send the email object to destination using setting specified in the configuration file.

So, our approach will be to keep the first part of action mailer as it is,  and override the deliver method used in the second step.

NOTE : For complete detail on sending email through rails is explained in this post.Here I will mention only the steps which is needed to deliver email through custom method. Step 1 and Step 2 are new addition to the last post and step 3 will override the configuration used earlier. Other things will remain same.

Step 1 : Write Your class which interact with the API

Let us call this file postman.rb and place it in the lib folder of our rails application.

NOTE : define your own code within the deliver! (will throw exception if some error) or deliver (will not throw any exception) method. I have simply shown a sample code from one of my application. It will not work for you as I have used dummy password

module MyFinanace
  class Postman

    def deliver!(message)
      deliver_type = message.header["deliver_type"]
      if deliver_type == "api"
        url = "http://mansel/esb-sunpower/outbound/emailService/"
        username = "mensalTemplate"
        password = "gateway13"
        rest_resource = RestClient::Resource.new(url, username, password)
        rest_resource.post prepare_payload(message), :content_type => "application/xml"
      else
        mail.perform_deliveries = false
      end
    end

     def prepare_payload message
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
        <emailRequest>
          <payload>
            <from>#{message.from.first}</from>
            <to>#{message.to.join(';')}</to>
            <cc>#{message.cc.join(';') unless message.cc.nil?}</cc>
            <bcc>#{message.bcc.join(';') unless message.bcc.nil?}</bcc>
            <replyTo>#{message.reply_to.first.to_s unless message.reply_to.nil?}</replyTo>
            <subject>#{message.subject.to_s unless message.subject.nil?}</subject>
            <body>#{message.body.to_s}</body>
            <contentType>text/html</contentType>
          </payload>
          <messageType>default</messageType>
        </emailRequest>"
    end

  end
end

So you can see that, We have redefined the deliver! method and making API call within it to mansel service. We pass it all the required detail like subject, to, from, body etc in the payload and left up to mansel to deliver the message.

STEP 2: Add your class defined above to the delivery method of rails ActionMailer class

Rails by default support smtp delivery. Since we have added our own class to deliver the email we need to tell ActionMailer about it. We can achieve it with add_delivery_method of ActionMailer . We need to specify it the time our application boot up, so be will create a file say my_mailer.rb in initializer folder of our application and add below lines to it.

require 'postman'
ActionMailer::Base.add_delivery_method :my_finanace_smtp, MyFinanace::Postman

So we have named our custom delivery method as my_finanace_smtp and pointed it to Postman module of MyFinanace class . Now, whenever we start our application, we will have our custom delivery method available to ActionMailer.

STEP 3: configure your environment file to use your custom deliver method

Since now we are using custom deliver method , which will be handled by API outside our rails application, We will replace the configuration used in development.rb file in step 1 of this post with below two line.

  config.action_mailer.default_url_options = {:host => 'localhost:3000'}
  config.action_mailer.delivery_method = :my_finanace_smtp

That’s all, now everything will remain same as in the last post, but your email will be delivered through your custom email deliver method.

Reference:

http://guides.rubyonrails.org/action_mailer_basics.html

Follow

Get every new post delivered to your Inbox.