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…
|