by sandipransing
Basically Enumerable mixin gives collection classes a variety of traverse, search, sort methods.
understanding ruby blocks i.e. proc
blocks are statements of code written in ruby. one can take them as similar to c language macro's
Different ways to define blocks
a = proc do
puts "hello"
end
a.call #=> hello
b = lambda do |u|
puts "hello #{u}"
end
b.call('sandip')#=> hello sandip
c = proc {|user| puts user }
c.call('sandip') #=> sandip
Passing block to enumerator
Lets assume we have collection array of strings and we want to print it
a = ['hi', 'sandip', 'how', 'you', 'doing', '?']
=> ["hi", "sandip", "how", "you", "doing", "?"]
a.each {|w| puts w }
q = proc {|w| puts w }
=> #
a.each(&q) #=>
hi
sandip
how
you
doing
?
a.map{|r| q.call(r)} #=>
hi
sandip
how
you
doing
?
Understanding symbol#to_proc
Symbol has method to_proc which converts symbol to block where symbol is taken as method to be executed on first argument of proc
How to_proc got implemented inside Symbol class
class Symbol
def to_proc
Proc.new { |*args| args.shift.__send__(self, *args) }
end
end
Lets have some examples
v = :even?.to_proc # equivalent to proc {|a| a.even?}
#=> #
q = [1, 2, 3, 5, 67]
q.map(&v)
=> [false, true, false, false, false]
Is there any shortcut?
Yes, there is shortcut to have block passed to enumerators on the fly using ampersand followed by colon (i.e. symbol)
q = [1, 2, 3, 5, 67]
q.map(&:even?) <=> q.map(&:even?.to_proc)
q.map(&:even?.to_proc)
#=> [false, true, false, false, false]
q.map(&:even?)
#=> [false, true, false, false, false]
Some handy examples
[1, 2, 3, 5, 67].inject(&:+) #=> 78
[1, 2, 3, 5, 67].inject(:+) #=> 78
[1, 2, 3, 5, 67].any?(&:even?) #=> true
[1, 2, 3, 5, 67].detect(&:even?) #=> 2
['ruby', 'on', 'rails'].map(&:upcase) #=> ["RUBY", "ON", "RAILS"]
Read More…
by sandipransing
`puts` converts ruby object into string by invoking to_s method on object.
The default to_s prints the object's class and an encoding of the object id. In order to print human readable form of object use inspect
locs = Location.find_by_sql('select * from locations')
Location Load (0.5ms) select * from locations
Puts Object internally invokes to_s method on object to print
locs.each do |l|
# it calls to_s method on object
puts l
end
#<Location:0x000000055bb328>
#<Location:0x000000055bb058>
puts object followed by subsequent invoke of inspect method outputs readable object
locs.each do |l|
puts l.inspect # prints actual object
end
#<Location id: 15, name: "Annettaside3", street: "71838 Ritchie Cape", city: "East Destanystad", state: "Utah", zip: "58054", phone: 123456, other_phone: 987654, staff_strength: 40, is_active: true, created_at: "2012-01-25 11:17:26", updated_at: "2012-01-25 11:17:26", country_name: "Korea">
#<Location id: 16, name: "Sporerbury4", street: "73057 Jerad Shoal", city: "South Kyliefurt", state: "Delaware", zip: "46553-3376", phone: 123456, other_phone: 987654, staff_strength: 40, is_active: true, created_at: "2012-01-25 11:24:48", updated_at: "2012-01-25 11:24:48", country_name: "Australia">
Read More…
by sandipransing
We all know Active Support library constantly keeps adding new extensions to ruby core library and hence rails framework.
Do you know now inside ruby class we can have class_attribute placeholder.
class A
class_attribute :counter, :access_time
end
A.counter = 12
A.counter #=> 12
A.new.counter #=> 12
Inheritance
class B < A
end
B.counter #=> 12
B.access_time #=> nil
B.access_time = Time.now
B.access_time #=> Wed Dec 28 18:55:06 +0530 2011
B.new.access_time #=> Wed Dec 28 18:55:06 +0530 2011
A.access_time = nil
Restricting instance from writing class_attributes
class V
class_attribute :counter, :instance_writer => false
end
V.new.counter = 12
NoMethodError: undefined method `counter=' for #
Other ways
a_class = Class.new{class_atrribute :counter}
a_class.counter = 13
a_class.counter #=> 13
a_class.new.counter #=> 13
p = Class.new { class_attribute :help, :instance_writer => false }
p.new.help = 'Got a second!'
NoMethodError: undefined method `help=' for #<#:0x7f8f9d5b1038>
p.help = 'Got a second!'
p.help #=> "Got a second!"
Read More…
by sandipransing
Ruby language is dynamic and robust. We can define methods inside ruby classes at runtime.
# bash
class A
define_method :a do
puts "hello"
end
define_method :greeting do |message|
puts message
end
end
A.new.a #=> hello
A.new.greeting 'Ram ram' #=> Ram ram
Can you imagine using dynamic methods below 24 lines of code is optimized to just 8 lines
To know more on below code read
# Earlier code
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_staff, :current_employee, current_admin
def authenticate_staff!(opts={})
current_staff || not_authorized
end
def current_staff
current_user if current_user.is_a? Staff
end
def authenticate_employee!(opts={})
current_employee || not_authorized
end
def current_employee
current_user if current_user.is_a? Employee
end
def authenticate_admin!(opts={})
current_admin || not_authorized
end
def current_admin
current_user if current_user.is_a? Admin
end
end
# New Version using dynamic methods
%w(Staff Employee Admin).each do |k|
define_method "current_#{k.underscore}" do
current_user if current_user.is_a?(k.constantize)
end
define_method "authenticate_#{k.underscore}!" do |opts={}|
send("current_#{k.underscore}") || not_authorized
end
end
Read More…
by sandipransing
requirement was to display decimal numbers which are having scale values present to be displayed in decimal format otherwise display them as integer.
Output expected
12.23 => 12.23
12.00 => 12
While rendering any object on html page by default "to_s" method gets executed.
So, i overwrote "to_s" method of BigDecimal class as below.
Anyone having better solution. Please reply with your solutions. Many thanks!
Put below code in file "config/intializers/core_extensions.rb"
class BigDecimal
alias :old_s :to_s
def to_s
return to_i.to_s if eql? to_i
self.old_s
end
end
Read More…
by sandipransing
Array of years using range
((yr=Date.current.year)-9..yr).to_a
#=> [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010]
Array of years using lambda
Array.new(10){|i| Date.current.year-i}
#=> [2010, 2009, 2008, 2007, 2006, 2005, 2004, 2003, 2002, 2001]
Array of months
Date::MONTHNAMES.compact
#=> ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
Array of abbreviated months
Date::ABBR_MONTHNAMES.compact
#=> ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
Array of abbreviated months with index (ps. collect_with_index is core extension method added to array)
Date::ABBR_MONTHNAMES.compact.collect_with_index{|m, i| [m, i]}
#=> [["Jan", 1], ["Feb", 2], ["Mar", 3], ["Apr", 4], ["May", 5], ["Jun", 6], ["Jul", 7], ["Aug", 8], ["Sep", 9], ["Oct", 10], ["Nov", 11], ["Dec", 12]]
OR
Date::ABBR_MONTHNAMES.compact.each_with_index.collect{|m, i| [m, i+1]}
#=> [["Jan", 1], ["Feb", 2], ["Mar", 3], ["Apr", 4], ["May", 5], ["Jun", 6], ["Jul", 7], ["Aug", 8], ["Sep", 9], ["Oct", 10], ["Nov", 11], ["Dec", 12]]
Read More…
by sandipransing
Wrong English is an often problem while developing any website product as
it gives bad view to website user and thus does direct impact on product.
BOSSMan is a ruby gem that interacts with yahoo web service and provides a
simplest way to overcome such errors.
Installation:
gem sources -a http://gems.github.com
gem install jpignata-bossman
Apply and get Application ID from yahoo developer network
URl https://developer.apps.yahoo.com/
Make sure to note it for reference
Usage in ruby app
require 'rubygems'
require 'bossman'
include BOSSMan
BOSSMan.application_id = "Your Application ID here"
Spelling Suggestions
text = BOSSMan::Search.spelling("gooogle")
=> #{"resultset_spell"=>[{"suggestion"=>"google"}], "responsecode"=>"200", "deephits"=>"1", "start"=>"0", "count"=>"1", "totalhits"=>"1"}}>
text.suggestion
=> "google"
More sophisticated way of use -
1. Create a YML file containing list of kewords
2. Load YML file
3. Iterate YML hash to find out spell suggestions
Example: spelling.yml
1 keywords:
2 gooogle:
3 Barack Oabama:
4 Indian:
5 Latuur:
keywords = YAML.load_file('spelling.yml')['keywords'].keys
puts "Correction suggested"
keywords.each do |keyword|
text = BOSSMan::Search.spelling(keyword)
if defined? text.suggestion
puts "#{keyword} => #{text.suggestion}"
end
end
Output
Correction suggested
gooogle => google
Barack Oabama => Barack Obama
Latuur => Latour
Analyze suggestions manually and make neccesary corrections..
Read More…
by sandipransing
Building PDF Document in ruby & rails application using prawn Library
Brief
Before getting started with this tutorial, I would like to thanks Greg and Prawn team for their awesome work towards ruby and rails community.
Installing prawn (core, layout, format, security)
gem install prawn
or
Add following line in rails environment file inside initializer block.
config.gem 'prawn'
Optionally you can specify version to be used and then run task
rake gems:install
Generating pdf using rails console
./script/console
pdf = Prawn::Document.new
It creates new pdf document object. Here you can additionally pass options parameters such as -
Prawn::Document.new(:page_size => [11.32, 8.49], :page_layout => :portrait)
Prawn::Document.new(A0) Here A0 is page size.
Prawn::Document.new(:page_layout => :portrait,
:left_margin => 10.mm, # different
:right_margin => 1.cm, # units
:top_margin => 0.1.dm, # work
:bottom_margin => 0.01.m, # well
:page_size => 'A4')
pdf.text("Prawn Rocks")
=> 12
pdf.render_file('prawn.pdf')
=> #
Here is output file generated [ click]
Now let's go through other goodness of prawn.
pdf = Prawn::Document.new('A3') do
- FONTS [click]
# Specify font to be used or specify path to font file.
font "times.ttf"
font("/times.ttf")
- TEXT [click]
text 'Sandip Ransing', :size => 41, :position => :center, :style => :bold
- STROKE LINE [click]
stroke do
rectangle [300,300], 100, 200
end
- IMAGE [click]
Display Local file system Image
image 'sandip.png', :height => 50, :position => :center, :border => 2
Scale Image
image 'sandip.png', :scale => 0.5, :position => :left
Display Remote image from Internet inside pdf
require "open-uri"
image open('http://t2.gstatic.com/images?q=tbn:kTG6gAKrnou2gM:http://www.facebook.com/profile/pic.php?uid=AAAAAQAQrLXvTWfyY2ANjttV8D1c0QAAAAnDHPFJe0pPFR84iIzXPKro&t=1")
end
- LINE BREAKS
movedown(20)
- TABLE/GRID [click]
data = [
["Name", {:text => 'Sandip Ransing', :font_style => :bold, :colspan => 4 }],
["Address", {:text => 'SHIVAJINAGAR, PUNE 411005', :colspan => 4 }],
["Landmark",{:text => 'NEAR FC COLLEGE', :colspan => 4 }],
["Mobile","9860648108", {:text => "", :colspan => 3 }],
["Education", {:text => "Bachelor in Computer Engineering", :colspan => 4 }],
["Vehicle", 'Hero Honda',"Reg. No.", {:text => "MH 12 EN 921", :colspan => 3 }],
["Additional", "GDCA", "class", 'First', ""],
[{:text => "Areas of Speciality", :font_style => :bold}, {:text => "Ruby, Rails, Radiant, Asterisk, Adhearsion, Geokit, Prawn, ....,...", :font_style => :bold, :colspan => 4}],
[{:text => "Website", :colspan => 2},{:text => "www.funonrails.com", :colspan => 3}],
[{:text => "Company", :colspan => 2},{:text => "Josh Software", :colspan => 3}]
]
table data,
:border_style => :grid, #:underline_header
:font_size => 10,
:horizontal_padding => 6,
:vertical_padding => 3,
:border_width => 0.7,
:column_widths => { 0 => 130, 1 => 100, 2 => 100, 3 => 100, 4 => 80 },
:position => :left,
:align => { 0 => :left, 1 => :right, 2 => :left, 3 => :right, 4 => :right }
- LINKS [click]
link_annotation([200, 200, 500, 40],:Border => [0,0,1], :A => { :Type => :Action, :S => :URI, :URI => Prawn::LiteralString.new("http://twitter.com/sandipransing") } )
link_annotation(([0, 100, 100, 150]), :Border => [0,0,1], :Dest => s"http://funonrails.com")
- PDF Security [click]
encrypt_document :user_password => 'hello', :owner_password => 'railer',
:permissions => { :print_document => false }
- Prawn Inline Formatting
Prawn-format supports inline text formatting that gives user enough flexibility to use html tags.
require 'prawn/format'
text 'This is Strong text', :inline_format => true
text 'This is bold text \n It should be on newline.', :inline_format => true
SAVE PDF File
end
pdf.render_file 'my.pdf'
!!! NOTE: As of time now 'prawn-format' is incompatible with latest prawn gem, It is compatible with prawn version <= 0.6 s
Read More…
by sandipransing
Before getting started with modules and mixins, lets first find out the
need of module & mixins in OOP.
In object oriented programming languages multiple inheritance is basic paradigm (child class extends behavior of base class).
C++ supports multiple inheritance.
Java does support same using interfaces.
In ruby language, multiple inheritance is achieved very easily using mixin
of modules & classes and that makes ruby as powerful language.
Ruby has classes, modules. Modules can be included inside other classes (mixins) to achieve multiple inheritance.
Modules
module Greeting
# here below is the instance method
# and that can be accessed using object of class ONLY
def hi
puts 'Guest'
end
end
Module methods can be called using scope resolution operator (::) or dot operator (.)
Greeting::hi
# => undefined method `hi' for Greeting:Module (NoMethodError)
It is obivous to have an error because we are calling class method and that is not present inside module.
Mixins
Lets include greeting module inside person class
class Person
include Greeting
end
person = Person.new
person.hi #=> "Guest"
Lets see how module methods can be defined. It can be done using either self or class_name.
module Greeting
# here below is the instance method
# and that can be accessed using object of class ONLY
def hi
puts 'Guest'
end
# Below are module methods
# this methods can be invoked
# using Greeting::hi
# OR Greeting.hi
def self.hi
puts 'hi Sandip'
end
# here is one more way to declare
# module methods
def Greeting.bye
puts 'Bye Sandip!'
end
end
Lets invoke methods
Greeting::hi #=> "hi Sandip"
Greeting.bye #=> "Bye Sandip!"
Extending class behavior using modules
class Person
def self.included(base)
base.extend Greeting
end
end
Got easy ?? Cheers!
Read More…
by sandipransing
Alias method in ruby
Ruby classes provides a alias_method that can be used to reuse the existing methods.
Consider a situation where you need different methods which has same code and ONLY
they have different names.
In this case alias_method uses suits best choice instead duplicating same code or
writing common method that will get used in all methods, as i did before.
Example, I have methods search, home, index all are doing same functionality.
Old approach
# URL /
def index
list
end
# URL /search
def search
list
end
#URL /home
def home
list
end
private
def list
# code here
end
Correct approach in ruby
def index
# code here
end
alias_method :home, :index
alias_method :search, :index
Attributes aliasing in ruby
Same way one can easily rename existing class attribute names
using alias_attribute method.
alias_attribute(new_name, old_name)
alias_attrinute :username, :login
More practical use
while deprecating attributes, methods in gems, plugins, extensions, libraries always
use aliases in order to maintain backward compatibility.
Got easy ??
that's where ruby rocks !
Read More…
by sandipransing
Ruby On Rails Installation on fresh ubuntu machine
Installation steps are applicable to ubuntu versions interpid, karmic koala.
Make necessary changes according to package manager provided by other
linux operating systems in order install ruby and rails.
Before getting started to installations make sure to build essential packages
on fresh ubutnu machine. Ubuntu machine has built in apt-get package manager
and that i loves because it is very to use as compared to other OS.
sudo apt-get install build-essential
Now there are many versions of ruby available including latest 1.9.2
But would like to prefer ruby version 1.8.7 as it is the most stable version
as of now.
I would like to recommend installtion of Ruby Enterprise Edition (REE) version as it is uses minimal system resources and consumes less memory.
Instrunctions to setup normal ruby and rails environment
1. Install Ruby, Rails, MySQL, irb and neceesary packages using single command
sudo apt-get install ruby ri rdoc mysql-server libmysql-ruby ruby1.8-dev irb1.8 libdbd-mysql-perl libdbi-perl libmysql-ruby1.8 libmysqlclient15off libnet-daemon-perl libplrpc-perl libreadline-ruby1.8 libruby1.8 mysql-client-5.1 mysql-common mysql-server-5.1 rdoc1.8 ri1.8 ruby1.8 irb libopenssl-ruby libopenssl-ruby1.8 libhtml-template-perl mysql-server-core-5.1 libmysqlclient16 libreadline5 psmisc
2. Install ruby gems
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
tar xvzf rubygems-1.3.5.tgz
cd rubygems-1.3.5
sudo ruby setup.rb
3. Create symbolic links to installation paths
sudo ln -s /usr/bin/gem1.8 /usr/local/bin/gem
sudo ln -s /usr/bin/ruby1.8 /usr/local/bin/ruby
sudo ln -s /usr/bin/rdoc1.8 /usr/local/bin/rdoc
sudo ln -s /usr/bin/ri1.8 /usr/local/bin/ri
sudo ln -s /usr/bin/irb1.8 /usr/local/bin/irb
4. Setup gemrc in order to avoid rdoc installation and to setup gem sources.
Add following lines to ~/.gemrc file
---
gem: --no-ri --no-rdoc
:benchmark: false
:verbose: true
:backtrace: false
:update_sources: true
:sources:
- http://gems.rubyforge.org
- http://gems.github.com
:bulk_threshold: 1000
5. Install rails
sudo gem install rails --no-rdoc --no-ri
Ruby Enterprise Edition i.e. REE (ruby 1.8.7) Installation
This will install ruby, rails, mysql, nginx and passenger
1. Download REE setup and install it
wget http://rubyforge.org/frs/download.php/68719/ruby-enterprise-1.8.7-2010.01.tar.gz /opt/ruby
cd /opt
./ruby/installer
2. Add ruby inside path
vi ~/.bashrc
# Add following line at the end of file
export PATH=/opt/ruby/bin:$PATH
Thanks to @vwadhwani!
Read More…
by sandipransing
1. Ruby http://tryruby.org
2. Hpricot http://hpricot.com
3. Regular expressions http://rubular.com
4. Exceptions http://hoptoadapp.com/
5. Application Performance http://newrelic.com
6. Ruby Doc http://www.ruby-doc.org/
7. Rails API http://api.rubyonrails.org/
8. Ruby gems sources http://rubyforge.org / http://gems.github.com / http://gemcutter.org
9. Listing remote gems from source gem list --remote --source http://gems.github.com
10. List of Rails Plugins http://wiki.rubyonrails.org/rails/pages/Plugins
http://www.agilewebdevelopment.com/plugins
Read More…
by sandipransing
1. To create local variables in ruby dynamically.
Use eval method in ruby
ree-1.8.7-2010.01 > eval("local=4")
=> 4
ree-1.8.7-2010.01 > p local
4
ree-1.8.7-2010.01 > eval("local_#{1}=4")
=> 4
ree-1.8.7-2010.01 > puts local_1
4
2. To create & get instance variables dynamically in ruby.
instance_varaiable_set & instance_varaiable_get methods are provided and no need to do it using eval.
ree-1.8.7-2010.01 > (0..3).each do |i|
ree-1.8.7-2010.01 > instance_variable_set("@instance_#{i}", i*i+1)
ree-1.8.7-2010.01 ?> end
=> 0..3
ree-1.8.7-2010.01 > @instance_0
=> 1
ree-1.8.7-2010.01 > @instance_2
=> 5
3. Dynamic constant variable creation in ruby
ree-1.8.7-2010.01 > class Example
ree-1.8.7-2010.01 ?> end
=> nil
ree-1.8.7-2010.01 > Example.const_set('A',200)
=> 200
ree-1.8.7-2010.01 > Example::A
=> 200
Read More…
by sandipransing
Eval method in ruby executes string/expression passed as parameter.
Example:
irb > eval("5+3")
=> 8
irb > eval("a=5")
=> 5
irb > eval("b||=a")
=> 5
Its part of ruby meta-programming and not recommended approach unless there is no any alternative to do.
Read More…
by sandipransing
Include gems/library required before getting started
require 'hpricot'
require 'net/http'
require 'rio'
# Pass website url to be scraped
url = "www.funonrails.com"
# Define filename to store file locally
file = "temp.html"
# Save page locally
rio(url) < rio (file)
# Open page through hpricot
doc = Hpricot(open(file))
Apply hpricot library to get right contents
doc.at("div.pageTitle")
doc/"div.pageTitle"
doc.search("div.entry")
doc//"div.pageTitle"
Hpricot API Reference click here
Read More…
by sandipransing
Ruby file accepts from command prompt in the form of array.
Passing parameters
ruby input.rb TOI DH TimesNew
Accessing parameters
# input.rb
p ARGV
# => ["TOI", "DH", "TimesNew"]
p ARGV[0]
# => "TOI"
p ARGV[1]
# => "DH"
Optparser : parses commandline options in more effective way using OptParser class.
and we can access options as hashed parameters.
Passing parameters
ruby input.rb -P"The Times of India" --category"article"
Accessing parameters
# input.rb
require 'optparser'
options = ARGV.getopts("P:", 'category')
p options
# => { 'P' => 'The Times of India', :category => 'article' }
p options['P']
# => "The Times of India"
Read More…
by sandipransing
In ruby, one can write multiple codes to remove multiple blank spaces inside strings (sentenses)
"Write your string here ".squeeze.strip
"This is my input string ".gsub(/ +/, ' ')
"Write your string here ".split(' ').join(' ')
Read More…
by sandipransing
Below is ruby code to establish manual database connection.
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "root",
:password => "abcd",
:database => "funonrails"
)
Snippet of database.yml file
common: &common
adapter: mysql
database: students_dev
username: root
password:
host: localhost
students_development:
<<: *common
database: students_dev
students_production:
<<: *common
database: students
Load database configurations from yml file
dbconfig = YAML::load(File.open('database.yml'))
ActiveRecord::Base.establish_connection( dbconfig[:students_development] )
Active Record Model & DB connection
class Student < ActiveRecord::Base
establish_connection "students_production"
set_table_name "student"
set_primary_key "stud_number"
end
Read More…
|