REFINEMENTS – RUBY MONKEY-PATCHING REDEFINED
Ruby classes are special in many ways. One of the most useful among these specialities is that, in Ruby, all classes are mutable. The ability to change the way classes behave at runtime(aka monkey-patching) has been used by many libraries and frameworks to decorate Ruby's core classes with additions and/or replacements. But good and evil are two sides of a coin. Anything that helps you a lot can also get you into problems.
Many patterns in Ruby are built around the ability to modify classes. But, the problem rises if a library patches code in a way the user does not expect (or want), or if two libraries try to apply conflicting patches. Sometimes, you simply don't want patches to be applied globally, and this is where refinements come in. Refinements are intended to allow monkey-patching only within certain limited scopes, like within a library that wants to use altered or enhanced versions of core Ruby types without affecting code outside the library.
Refinements are defined in a module using the refine method. It takes a single argument, the class you want to change the behavior of, as well as a block. Inside this block you're going to define the methods you want to change the behavior of. See the code sample below.
module RefineString
refine String do
def upcase
self.downcase
end
end
end
The above code defines a refinement. Now this is how you will be actually using it.
class TestRefinement
def modify_string
test_string = “this Is A TesTSriNG”
test_string.upcase #will give “THIS IS A TESTSTRING”. Ruby default
end
using RefineString
def testing_refinement
test_string = “this Is A TesTSriNG”
test_string.upcase #will give “this is a teststring”. Refined
end
end
Looks weird, huh? What I did now is that I changed the default String::upcase function to down-case the string instead of up-casing it.
Once you're in the scope you need to use the refinement, call the using method with the module holding the monkey-patch/ monkey-patches (as they can hold more than one), you want to activate. At this scope, or any deeper scope, the refinement will be active. As of now, a using call affects all of the following scopes related to where it is called:
- The direct scope, such as the top-level of a script, the body of a class, or the body of a method or block
- Classes down-hierarchy from a refined class or module body
- Bodies of code run via eval forms that change the "self" of the code, such as module_eval
Note that refinements applied in a class will be carried over to its subclasses. That means, if you are using my_refinements_module in your ParentClass, your ChildClass < ParentClass will have the refinements even if you don't explicitly say using my_refinements_module your ChildClass. So, when using refinements, one must know everything about the calling hierarchy to foresee method calls and expected results.
You can get the refinements version of ruby from the r29837 of trunk, and apply the patch. Here is how you do it using rvm.
$ curl -O http://stuff.judofyr.net/refinements.diff
$ rvm install ruby-head-r29837 –patch refinements.diff
$ rvm ruby-head-r29837
monkey-patching has always been a risky prospect. It is scary that you will have to check for refinements before you inherit a class. So, if you are using one, make sure that its details are well documented along with your code. Monkey-patching is not encouraged to be used by a good programmer. But, refinement makes it less dangerous, and only 'less' dangerous.
–
Mukesh
PDF generation in rails with wicked_pdf
Recently my friend was working on a project that had a requirement to export the html page to PDF. He had some issues setting this up. So I thought I would write this article, so that it will be helpful for anyone who faces the same issue. It’s easy getting your pdf in rails as long as you follow the right steps ;) (But unfortunately my good friend doesnt always do that for some reason of his own - No offense intended ;) )
If you are using Rails, then you have this wonderful rubygems where you can find a no of gems for pdf generation. The suggested ones are prawn and wicked_pdf.
Which one to chose ?
For me wicked_pdf is very simple to understand and it gets your job done very quickly if you follow all the right steps, while Prawn restricts you to the old table, grids layout. But ultimately its you who will have to decide which to use depending upon your specific requirements.
I will be using wicked_pdf and ubuntu.
Wicked_pdf
Wicked_pdf uses a shell utility Wkhtmltopdf to serve a PDF file to a user from a HTML page. In other words, rather than dealing with a PDF generation DSL of some sort, you simply write an HTML view as you would normally, then let Wicked take care of the hard stuff
Now what is wkhtmltopdf ?
Wkhtmltopdf is an c++ executable that wicked_pdf gem essentialy wraps. It works great for pdf generation of tables reports etc. The WK in wkhtmltopdf stands for webkit which is the browser engine that is used to render HTML and java-script Chrome uses this same engine.
Installation
Since we use Ubuntu for development I will be covering steps for installations for ubuntu machines. It wont be hard for you to change the commands a little bit according to your OS.
Installing it simply via
sudo apt-get install wkhtmltopdf
on Ubuntu will install a reduced functionality version which is probably not what you want. According to the manual the reduced functionality version does not include the following features.
Try uname -m
sudo apt-get install openssl build-essential xorg libssl-dev libxrender-dev
tar xvjf wkhtmltopdf-0.11.0_rc1-static-amd64.tar.bz2
sudo mv wkhtmltopdf-0.11.0_rc1-static-amd64 /usr/local/bin/wkhtmltopdf
which wkhtmltopdf
Add this to your Gemfile:
gem 'wicked_pdf'
You may also need to add the following to your config/initializers/mime_types.rb
Mime::Type.register "application/pdf", :pdf
Basic Usage:
class Invoice < ApplicationController
def show
respond_to do |format|
format.html
format.pdf do
render :pdf => "invoice"
end
end
end
end
If you need to include stylesheets and javascript inside the generated document, the wicked_pdf gem has helpers for that
<%= wicked_pdf_stylesheet_link_tag "pdf_stylesheet" -%>
<%= wicked_pdf_javascript_include_tag "pdf_javascript" %>
Some tweaks and tips
If you need to hide some links in your generated PDF document then you can use a custom stylesheet which defines the properties for print media and can include the same using the above helper method.
Eg: You have a button on your html page and you dont want that to be displayed when you generate the PDF.
If you have the following link with css selector "print_friendly"
<%= link_to "Print" , "http://example.com/download", :id=>"print_friendly" %>
and have a stylesheet with the css properties for print media as
@media print {
#print_friendly{
display:hidden;
}
}
then the link wont be visible inside the generated PDF document.
If your page has a lot of javascript and needs longer time for rendering then you can add the following the wicked_pdf
wkhtmltopdf.exe --javascript-delay 15000 http://example.com/downloads
Some common Issues
1. Runtime Error
RuntimeError in XxxxController#show
Failed to execute: /usr/bin/wkhtmltopdf --print-media-type -q - - Error: PDF could not be generated!
Rails.root: /apps/rails/show
Check the location of your wkhtmltopdf using which wkhtmltopdf and also run a bundle update command as sometimes your gem in gemfile would be configured with the wrong path.
2. Is wkhtmltopdf-binary necessary to generated PDF files ?
No
If you have installed the system libraries and have configured the path correctly in your app correctly, you dont need to install he wkhtmltopdf-binary gem seperately.
3. Wicked_pdf not rendering graphs with HighCharts
Wkhtmltopdf doesn't handle transparency/shadows properly and can result in unpredictable results. So the workaround is to add the following options to yo2ur highcharts
f.options[:plotOptions][:line] = { :animation => false, :shadow => false, :enableMouseTracking => false }
As I said earlier it’s easy getting your pdf in rails as long as you follow the right steps ;)
--
Manu S Ajith
[JTK] How to kill a rails server, who is working as a deamon?
$rails s , command has a -d (detach) option to let run your application run as a daemon and to stop this process you need to kill the process. Given below is a small shell command that will find the process id of our rails application and kill it for us.
kill $(lsof -i :3000 -t)
The meaning of the above command is to find the process id of the process which is running in port number 3000 and send to it the KILL signal.
A handy little command, which has not technical importance, but nice to know.
—
Issued in the interest of new and novice programmers.. :)
How to test drive rails 4?
As you all know, almost everyone in the rails or ruby community is excited about the upcoming rails 4 and its exciting features. For those who wish to try out the latest release of Rails 4, can do so by following these simple steps
Clone the latest code:
git clone https://github.com/rails/rails.git
move into that directory and install all the dependencies of rails
cd rails
bundle install
cd ../
Now lets create a new rails 4 application
ruby rails/railties/bin/rails new APPNAME --dev
All finished, now to run your rails application as usual
cd APPNAME
bundle install
bundle exec rails s
—-
Harisankar P S
—-
For migrating your rails application from Rails 3 to Rails 4 contact info@rubykitchen.in
Model : update_attribute & update_attributes
Presently it seems lot of people are confusing between the functionality of update_attribute and update_attributes. The purpose of these functions can be understood from their name itself. the first one update_attribute would update a single attribute of the model
Its used as
@users = User.find(1)
@users.update_attribute(:attribute_name,"attribute_value")
and the later update_attributes updates a whole set of values in the model
@users = User.find(1)
@users.update_attributes(attribute_1:"attribute_1_value"),attribute_2:"attribute_2_value")
Now the important differentiator of these two functions is that the first function update_attribute updates an attribute without running any of the validations mentioned..
So keep that in mind when you are using the update_attribute function, else at times you will find values you didn't expect to be entered into the database found in them.
—
Happy Coding
Harisankar P S
Want to Learn Rails?
Well I have been hearing a lot from people in facebook, google groups and online forum wanting to learn Rails. There question is simple “I want to learn Rails”, “How do I learn Ruby on Rails?”, “How do i become a Ruby on Rails programmer?”. Well the funny feeling I get while reading these questions is that, its the exact questions I posted in Google Groups, forums, etc when I wanted to start learning Rails and Ruby couple of years ago. So I though of giving back to the community and to my company blog, by posting on how to learn rails, and answer a few questions every newbie always have.
Q) How to learn Ruby on Rails?
Well to get started I would suggest this Rails Tutorial. Excellent tutorial, with details explanation. Build for people with little or no knowledge in Ruby. Further more it also teaches and introduces a newbie to Git and TDD.
If you don’t like reading from the web, and prefer books then I suggest Agile Web Development With Rails by Sam Ruby, Dave Thomas, David Heinemeier Hansson. The advantage of using rails is the ability to become more agile and roll out features faster. To be honest, I am not much of a fan of books ( technical), so if you are going to spend money then I suggest buying this book.
Now the one that really helped me learn Ruby and Rails was the community. Find a local Ruby user group, participate in its discussions, take part in its monthly meetups. These will help you find personal mentors and a lot of cool people like you who knows Ruby is worth learning.. :D
Those from Kerala India, can join the Kerala Ruby User Group Mailing List Also read as much materials you can find about ruby and rails, reddit is a good source of interesting news for Ruby.
Q) Is it required to know Ruby before you learn rails?
Well from experience the answer is
. You don’t have to know ruby to learn rails, but those have do can learn it much faster, and understand the reasons behind the various jargons used in rails. But from my personal experience, as a person who learned Rails before properly understanding Ruby. If you have a better understanding of the ruby language, then the picture you have about the possibilities with rails would become limitless.. Its like you won’t feel Rails can limit you, in anyway.
Q) How can I learn Ruby?
Well Ruby has been around for a long time, there are plenty of how to guides and basic tutorials in Ruby. So a quick Google will get you a lot of results. Some good websites that I would suggest is
For those who wish to have a cheat sheet available to help you, can use this website http://overapi.com/ruby/Q) How long will it take to learn Ruby/Rails? Well I do not have a proper answer to that one, I have been working in ruby for some time now. And even does it for a living, but I still believe that I have a lot to learn. Every new project has been challenging and has introduced me to more and more possibilities with Ruby. Thus I guess as they say, the possibilities are limitless as the Human Imagination.
My advice to beginners would be to be, not concerned about how long it would take, and just concentrate on learning. Try out various ideas that you might have, one good exercise that I did was try to implement all the commands in a linux terminal through ruby. Get to know the community, try to contribute to various opensource projects and always keep on coding… =)
Happy coding..
——
Harisankar P S,
Chief Innovations Officer.
PS: this is just my list, if you know some good online resources. Please do add them as comments, it would help those who are starting out with Ruby and Rails. Also sorry for any typo or grammatical errors.
How to turn on, VIM syntax highlighting
If you guys are using the vi editor in ubuntu, like I do then you guys would have also noticed that - it would be great if there was syntax highlighting, To unlock syntax highlighting and whole lot of features in VIM we need to install the full package of vim.
go to your terminal and write the command
#apt-get install vim-fullOnce this package in loaded you can turn on the syntax in your vim by using this command ” :syntax enable “. Now your programming experience would become much more hazel free.
If you hate writing that command every time you enter vim , then there is even a solution for that as well.
go to your terminal and write the commands
vim /etc/vim/vimrcThere you will find some line saying :
" Vim5 and later versions support syntax highlighting. Uncommenting the next
" line enables syntax highlighting by default.
"syntax onThere just remove the double quote( ” ) in the last line(“syntax on) and the syntax will be on by default now onwards in your VIM.
Happy Coding
How to make self executing ruby scripts in Linux?
To run a ruby program we use the command ruby
ruby program_name.rb
Ruby being an interpreter style language, each line is implemented one after the other and executable object code file is created for reuse like in case of compiler languages C, C++, etc.. To run a ruby code you need a ruby interpreter installed in your system.
Linux (all UNIX like operating systems) has a way of executing a file that can help make a script self executable (that is making a ruby script ruby by just calling its name, with no need to specify the interpreter program). Its called #!. Dennis Ritchie, who introduced it, referred it as hash-bang though over the course of time it came be known by many names such as shebang/hashbang/pound-bang/hash-exclam/hash-pling.
This #! character are never used alone, it is followed by the location of the interpreter program using which you want to run that particular file (script).
Now to make our ruby script executable we need to add to the first line the following statement
#!/usr/bin/rubyputs "The ruby code, starts from line 2"
How does this work?
A program is executed using a tool known as program loader. In linux when a program loader loads the file for execution and sees that there is #! notation in the first line, it would understand that this program needs to be passed to an interpreter program for execution. In case our ruby script when it gets executed ( $./program_name.rb) the program loader would pass it on to the ruby interpreter program that is defined in the hash-bang line as /usr/bin/ruby.
Thus the program loader would pass the file name and path to the ruby interpreter, in short the command $ruby program_name.rb ( $/usr/bin/ruby program_name.rb) would be execute.
$chmod 755 program_name.rb
Following these steps you can make a ruby scrip executable.
Note :-
The above mentioned method is not for ruby alone, any script can be made self executable using the above mentioned steps. We just have to change the program that is suppose to execute the program .
-
#!/bin/sh -
#!/bin/csh -
#!/usr/bin/perl -T -
#!/usr/bin/php -
#!/usr/bin/python -O -
#!/usr/bin/ruby
Also the above mentioned is the location of the interpreter program if its in a different location then you will have to use that location or could use env - enviornment variable in linux thus the hash-bang statement changes to
#!/usr/bin/env ruby
That is the interpreter is searched among the enviorment variable, thus during run time the appropriate interpreter would be searched and used. For more details see the env wikipedia page
Happy Coding…
—–
This blog post is reposted from Tech.HsPS.in, the technical blog authored by Harisankar P S ( Chief Innovations Officer of Ruby Kitchen)
Setup PostgreSQL and its libraries to work with rails
Recently lot of poeple have been asking me why they are not able to install the pg ( postgresql) gem even after install PostgreSQL server in their system?
Well the answer is simple, the pg gem, requires the PostgreSQL development libraries to build native extensions to communicate with the PostgreSQL server. Native extensions refer to building ruby extensions or wrappers for exisiting C or C++ library.
One can install the development libraries of PostgreSQL by installing the libpg-dev package.
The command below would install the last version of PostgreSQL available in the repository and its development libraries.
Ubuntu:
sudo apt-get install postgresql libpq-dev
CentOS / RedHat
yum install postgresql libpg-dev
Trying gem install pg, should install everything smootly..
Happy Coding.. :)
—-
Harisankar P S,
Chief Innovations Officer,
Ruby Kitchen
[Just to Know] How to install ruby via source in Ubuntu
Hi there
This blog post is for old style programmer who wish to install ruby via compiling the source code, like how I do it. This blog post is written in a just to know basis.
The source code of ruby can be downloaded from ruby's official website : http://www.ruby-lang.org/en/downloads/.
Dependency for Ruby and Ruby on Rails : libreadline, libyaml, libxml, libssl, zlib1g.
In ubuntu you can have these libraries installed via the command line ( or if you are so old fashion you may google and find the source code for these packages as well)
$sudo apt-get install build-essentails zlib1g zlib1g-dev libreadline-dev libyaml-dev libssl-dev
After installing the dependency download the source code and extract it ( please not the installation will proceed if you miss some of the dependencies but missing then would make gem, bundle, irb to not function properly).
First extarct the code :
$tar -zxvf [Name of ruby source code file].tar.gz
the configure the source code
$./configure
the finally you make and install
$make && sudo make install
To check if ruby is install you can use the command
$ruby -v
or try out interactive ruby (irb)
$irb
Now for those who are wondering how to install the latest version of rails, use the command:
$sudo gem install rails