Featured

How to query Class to get information in Ruby Meta programming

module MyModule
def module_method
end
end

class Parent
def foo
end
end

class Child < Parent
include MyModule
def child_class_method
end
end

obj = Child.new
puts obj.class #### Child
foo = obj.class
puts foo.name #### Child
print foo.ancestors #### [Child, MyModule, Parent, Object, Kernel, BasicObject]

print foo.included_modules #### [MyModule, Kernel]
print foo.singleton_class? #### flase
puts foo.singleton_class.singleton_class? #### true
puts foo.include?(MyModule) #### true
puts obj.instance_of? Child #### true
puts obj.instance_of? Parent #### false

puts obj.kind_of? Child #### true
puts obj.is_a? Child #### true
puts obj.kind_of? Parent #### true
puts obj.kind_of? MyModule #### true
puts obj.kind_of? Object #### true
puts obj.kind_of? Module #### false
puts obj.kind_of? Class #### false
puts obj.kind_of? Kernel #### true
puts obj.kind_of? BasicObject #### true
puts Parent.kind_of? Class #### true
puts Parent.new.kind_of? Class #### true
print Parent.instance_methods ####
puts
print Parent.methods ####
puts
puts Parent.instance_methods – Parent.methods
print Parent.methods – Parent.instance_methods
puts obj.is_a? Child #### true ## is_a? is same ad kind_of? means if a class is present in the ancestor tree
puts obj.is_a? Parent #### true
print obj.methods #### return all the methods available in the instance along with the methods in available in the hierarchy
puts
def obj.my_method
‘its is a singleton methods’
end
puts obj.methods(false) ## return only signleton methods available to that object or we can also use
puts obj.singleton_methods ## return only signleton methods available to that object

print Child.instance_methods ## All the methods defined in class and ancestors
puts
puts Child.instance_methods(false) ## All the methods defined in class only not in the anscestor

puts ‘########### method_defined? is called on an class’
puts Child.method_defined?(:child_methods) ## check Method present inside the class
puts Child.method_defined?(:child_class_method) ## Method present inside the class
puts Parent.method_defined?(:foo) #### true, method defined inside the parent class
puts ‘######## Respond to is called on an object ###############’
puts obj.respond_to? :child_class_method #### Find if a instance methods responds to a method
puts obj.respond_to? :clone #### Find if a instance responds to a method
puts obj.respond_to? :module_method #### Find if a instance responds to a method
puts obj.respond_to? :foo #### Find if a instance methods responds to a method

puts ‘######### List of all public, private & protected methods of class #########’
puts ‘Public methods of child class’
print Child.public_methods
puts
puts ‘Private methods of child class’
print Child.private_methods
puts
print Child.protected_methods
puts ‘Public method of the class itsel’
print Child.public_methods(false)
puts ‘Private method of the class itsel’
print Child.private_methods(false)
puts ‘Protected method of the class itsel’
print Child.protected_methods(false)

puts ‘######### List of all public prive protected methods of instance #########’
print obj.public_methods
puts
print obj.public_methods
puts
print obj.protected_methods

puts (‘##### check if a method of a type is defined for class ####’)
puts Child.private_method_defined? :initialize
puts Child.public_method_defined? :new
puts Child.public_method_defined? :include?
puts Child.protected_method_defined? :new

puts obj.singleton_class.instance_methods(false) ## it will return single methods in a class
puts obj.singleton_methods ## it will return single methods in a class

Rails 6 secrets/credentials

Rails 6: Define And Manage credentials file for each environment

example files inside the app/config/credentials folder will be as:
development.key
development.yml.enc
production.key
production.yml.enc
test.key
test.yml.enc

These file can be created by the following commands:
from the root of the application run the following command:
EDITOR=”gedit –wait” bin/rails credentials:edit -e d
development.key, development.yml.enc files will be generated and they can be edited inside vim or gedit in editor of your preferrence.

EDITOR=”gedit –wait” bin/rails credentials:edit -e t
test.key, test.yml.enc these 2 files will be generated after running above command to store the test environment credentials.

EDITOR=”gedit –wait” bin/rails credentials:edit -e p
production.key, production.yml.enc these 2 file will be generated to store the credentails for production environment.

These credentials can be accessed as:

 Rails.application.credentials.xyz

Ruby Meta programming trick

Extending a module which is present inside another module so that the module methods can be accessed as class methods/singleton class methods.

 module MyModule
	def self.included(base)
		base.extend ClassMethods  ## extending the module inside 
					  ##	class included this module		
	end
	
	def foo
		puts 'foo called'
	end
	
	module ClassMethods
		def bar
			puts 'bar called'
		end
	end
 end
 
 class MyClass
	include MyModule
 end
obj = MyClass.new  
obj.foo		## foo called
MyClass.bar 	## bar called

this same trick is used while writing active support concerns.

#2 trick: Return the name of the undefined constant :

class Foo
end

def Foo.const_missing(name)
	name
end
 
puts Foo::UNDEFINE_CONST  ## UNDEFINE_CONST
puts Foo::Vidur		  ## Vidur	
#3 trick: Return the a class that does not exists: 
module Famous
	def self.const_missing(name)
		const_set(name, Class.new)
	end 
end
obj = Famous::Bar.new
puts obj.class

method callback in ruby

  1. method_added
  2. method_removed
  3. method_undfined
  4. singleton_method_added
  5. signleton_method_removed
  6. signleton_method_undefined

Example: are with ruby 2.2.6p396

1. method_added

 class MyClass
	def foo
	end
	
	def self.method_added(method_name)
		puts "Adding '#{method_name}'"
	end
	
	def bar
	end
 end
 ## o/p
  Adding 'bar'
  Adding 'object_bar'

method_added will be called whenever a new instance method is added in the Myclass as instance method after defining the self.method_added in the class.

2. method_removed: this will be called when an instance method get removed after defining it with in the class.

Example:

 class MyClass
 
	def human
	end
	
	remove_method :human
	
	def self.remove_method(method_name)
		puts "#{method_name} is removed"
	end


	def foo
	end
	
	remove_method :foo
	
	def self.bar 
	end
	
	class << self
		remove_method :bar
	end
 end
 
 
 ##o/p:
 foo is removed

3. method_undfined

 class MyClass
 
	def person 
	end
	
	undef_method :person  # no output 

	def self.method_undefined(method_name)
		puts "#{method_name} is undefined"
    end

	def animal
	end
	
	def cow
	end
	
	undef_method :cow       # cow is undefined
	undef_method :animal	# animal is undefined
	
 end

 

4. singleton_method_added:

Notice: class methods in like an alias to singleton method both are same.

  class MyClass
	def foo
	end
	
	def self.bar
	end
	
	def self.singleton_method_added(method_name)
		puts "#{method_name} added"
	end
	
	def self.name
	end
	
	def MyClass.last_name
	end
 end
 
 ## o/p: 
 # singleton_method_added added
 # name added
 # last_name added

5. signleton_method_removed

 module MyClass
	def self.foo
	end
	
	class << self
		remove_method :foo              ## o/p: nothing
	end	
	
	def MyClass.singleton_method_removed(method_name)
		puts "#{method_name} removed"
	end
	
	def self.bar
	end
	
	class << self
		remove_method :bar		## o/p: bar removed
		remove_method :hello		## o/p: NameError method not defined
	end

end
 

6. signleton_method_undefined

 class MyClass
	def MyClass.singleton_method_undefined(id)
		puts "#{id.id2name} is undefined"
	end
	
	def self.foo
	end
	
	class << self
		undef_method :foo
	end
 end
 
 ## o/p:  foo is undefined
 

Name: here id same as id.id2name

include vs extend, included vs extended vs inherited callbacks in ruby Meta programming

include: By using this methods get included as instance methods of the included module in the including class/module.

extend: By using this methods get included as class methods of the module/class inside the extending class/module.

extended: This methods inside the extended class on extending this class/module.

included: This method inside the included class on including this class/module.

Example:

  module Logging
	def log(level, message)
		File.open('extend.txt', 'w') do |f|
			f.write("#{ level } : #{message}")
		end
	end
	
	def self.extended(base)
		puts "#{self} extending in #{base}"
	end
	
	def self.included(base)
		puts "#{self} included in #{base}"
	end
 end
 
 class MyClass
 extend Logging
	def self.do_something
		begin 
			throw NoMethodError
		rescue StandardError => e
			log :error, e.message
		end
	end
end

class AnotherClass
	include Logging
	def do_something
		begin 
			throw NoMethodError
		rescue StandardError => e
			log :error, e.message
		end
	end
end

MyClass.do_something
AnotherClass.new.do_something

prepend: This is used methods of the class/module of the prepended class/module in the prepending class/module.

module MyModule 
	def log(level, message)
		File.open('MyModule.txt', 'w') do |f|
			f.write("#{ level } : #{message}")
		end
	end	
end

class MyClass
	prepend MyModule
	
	def log(error, message)
		File.open('MyClass.txt', 'w') do |f|
			f.write("#{error}: #{message}")
		end
	end	
	
	def do_something
		begin
			throw NoMethodError
		rescue StandardError => e
			log :error, e.message
		end
	end
end
	
	obj = MyClass.new
	obj.do_something


inherited: this method will be called inside the inherited class on inheriting a class inside another class.

 class MyModule
	def foo
		"Method inside MyModule"
	end
	
	def self.inherited(base)
		puts "#{base} inherited #{self}"
	end
 end
 
 class MyClass < MyModule

 end
 
 class YourClass < MyModule
 
 end
 obj = MyClass.new
 obj.foo
 
## o/p: 
# MyClass inherited MyModule
# YourClass inherited MyModule

included, extended and inherited are also called callback methods.

Get information about ruby variables Ruby Meta programming

$my_global_variable = 'Global variable'
CONSTANT = 'My constant' 

class Parent
	@@parent_class_variable = 'parent class variable'

	 PARENT_CONSTANT = 'Parent class constant'
	 
	 @parent_eigen_class_instance_variable = 'Parent Eigen class instance variable'
	 
	 def initialize
		@parent_class_instance_vaiable = 'Parent class instance variable' 
	 end
end

parent = Parent.new
puts "Parent instance variable = #{parent.instance_variables}"    #### Parent instance variable = [:@parent_class_instance_vaiable]

class Child < Parent
	@@child_class_variable = 'Child class variable'
	@child = 'child class eigen class variable'
	CHILD_CONSTANT = 'Child class constant'

	def initialize
	super
		@child_instance_variable = 'Child class instance variable' 
	end

	class InnerClass
	end	
end

child = Child.new
puts "Child class instance variables = #{child.instance_variables}"  ### Child class instance variables[:@parent_class_instance_vaiable, :@child_instance_variable]

puts "child class eigen class instance variables #{Child.instance_variables}"  #### child class eigen class instance variables [:@child]
puts "child class variables #{Child.class_variables}" ##### child class variables also include parent class class variables child class variables [:@@child_class_variable, :@@parent_class_variable], Here it also proves classes are instance and classnames are constants

puts "Gloabal variables #{global_variables}"    ## gives all global variables
puts "Local variables #{local_variables}"		## gives all global variables

puts "Print Top level constants #{self.class.constants.include?(:MY_TOP_CONSTANT)}"		## gives result of top level constants now checking our top level constant

#### Get and set value of the instance variables
puts Child.instance_variable_get :@child_instance_variable     ###### ==> Print Top level constants true
Child.instance_variable_set :@child_instance_variable, 'updated value'
puts Child.instance_variable_get :@child_instance_variable     ###### ==> updated value

#### Get and set value of the class variables
puts Child.class_variable_get :@@child_class_variable     ###### ==> Print Top level constants true
Child.class_variable_set :@@child_class_variable, 'updated child class variable value'
puts Child.class_variable_get :@@child_class_variable     ###### ==> updated child class variable value


#### Get and set value of the class constants
puts Child.const_get :PARENT_CONSTANT
Child.const_set :PARENT_CONSTANT, 'Set parent class constant'
puts Child.const_get :PARENT_CONSTANT

Ruby code runs inside the Object class.

Singleton class or Eigen class in Ruby Metaprogramming.

Singleton class and Eigen class are same.

examples:

class MyClass
    def eigenclass    
        class << self      
           self    
        end  
    end
end
irb> MyClass.eigenclass          ####=> #<Class:#<MyClass:0x270cff0>> is the eigen class

All methods that prefix with self get defined inside the eigen class of the current class.

example:

class MyClass
	def self.my_method
		'eigen my_method'
	end
	class << self
		def new_method
			'eigen new_method'
		end
	end
end

puts MyClass.my_method              ##=> eigen my_method
puts MyClass.new_method             ##=> eigen new_method

both the methods are defined inside the eigen class and can be accessed using class name these are class methods.

the instances of the above class do not have the scope to access the class methods so on accessing, it will call method_missing function in the object class that throw undefined method exception.

puts MyClass.new.new_method 

`<main>': undefined method `new_method' for #<MyClass:0x82de80> (NoMethodError)

Singleton methods in ruby meta programming.

Notice: Singleton methods have the highest priority, they will be called first if methods with the same name exists in the class itself or super class or eigen class or included module or hierarchy order.

class MyClass
      def my_method
            'inside my_class_instance_method'
      end
end

obj = MyClass.new

def obj.my_method
      'Inside singleton method'
end

puts obj.my_method                 ####====> Inside singleton method

my_method is the singleton method and have highest method priority with same name.

Accessing constants inside class and modules.

class MyClass
MyConstant = 'My Class constant'          ##====> My Class constant
end

puts MyClass::MyConstant

module MyModule
           @@module_variable = 'module class variable'
           MyModule = 'My Module constant'
          def self.module_variable
               @@module_variable
          end

          def instance_method_first
                'inside instance method'
          end
end
puts MyModule::MyModule                        ##====>My Module constant
puts MyModule.module_variable              ##====>module class variable

Sidekiq with Rvm with CentOs 7

CentOs 7 having rvm 1.29.10, ruby 2.4.0p0 and Rails 5.2.3

  1. First we need to include sidekiq gem in the gemfile then bundle install.
  2.  create a RVM wrapper: I am using “punj” as the name of my wrapper you can set any name.

    rvm alias create punj ruby-2.4.0@rails5.1.2

3. Now copy the file content at: https://github.com/mperham/sidekiq/blob/master/examples/systemd/sidekiq.service

in your centos at: /lib/systemd/system/sidekiq.service

4. Now updated in the file:

Type=simple
WatchdogSec=10
WorkingDirectory=/home/vidur/office_workspace/tukaweb_old
ExecStart=/bin/bash -lc ‘/home/vidur/.rvm/wrappers/punj/bundle exec sidekiq -e production’
User=vidur
Group=vidur
UMask=0002

WorkingDirectory = path to the working directory of project.

5. Now run the following commands:

sudo systemctl enable sidekiq.service

# If you have made changes to your service, you may need to reload the daemon

sudo systemctl daemon-reload

To start the demon:

sudo service sidekiq start

To enable the automatic restart of the service on system reboot.

sudo systemctl enable sidekiq.service