James Crisp

Software dev, tech, mind hacks and the occasional personal bit

Category: Ruby / Rails (Page 2 of 6)

Ruby 1.8 Scoping and Blocks

Quick ruby quiz.. after these two lines execute, what is the value of number?

>> number = 5
>> (1..10).each {|number| print number}

Well, number will be 10, thanks to the block being run and re-assigning the value of number. This can cause you some pretty subtle bugs if you happen to have the same name for a local/function argument, and as a variable name in a block.

In C#, the compiler is kind enough to tell you that this would be a very bad idea and give you an error.

And thanks to Sudhinda for commenting – this has been fixed in Ruby 1.9. In 1.9, the variable used as the argument in the block does not affect the variable outside the block.

ACS Alm Talk: Presentation Wrap Up & Slides

Thanks everyone who came along last night. It was a fun session, with a lot of lively discussion, especially around project management and software design. As mentioned during the talk, you might want to check out nRake for .NET builds and psDeploy for Powershell deployments. Here are the slides from the talk. If you have any more questions or areas to discuss, please feel free to drop me a line.

nRake now on IronRuby

nRake, the premier project and build template for .NET projects using the Rake build system now has a branch for .NET4 using IronRuby. Projects are also updated to VS2010 format, and Albacore gems are now updated to 0.1.5.

Check out the IronRuby .NET 4 branch of nRake.

or the check out the IronRuby .NET 2 / 3.5 branch of nRake.

Master branch is still using MRI ruby 1.9. However, plans are to change over to IronRuby for master branch in the future. IronRuby is now performing well enough and sufficiently compatible to support .NET builds. IronRuby has advantages around size (smaller download) and more exciting interop possibilities with .NET code.

Podcast from ALM Conference

At the ALM Conference, Richard interviewed me for a podcast on the Ultimate ALM Environment circa 2010 as well as a little on build and deployment automation. Check out the podcast on Talking Shop!

nRake – Rake builds for .NET

Fed up with XML based builds that are hard to maintain, refactor and extend? Rather than trying to fix this with more xml and community tasks, or re-invent the wheel, let’s use Rake. Rake is a mature build system developed by the ruby community which can be applied equally well in the .NET world.

To help you get started quickly, I’ve put together nRake. nRake provides a template C# .NET solution with a nice directory structure (src, tools, lib, etc), a Rake build, NUnit tests, templated app and web configs for different environments (eg, dev, uat, prod, etc) and Continuous Integration server sample config files. It comes with everything you need – no additional libraries or downloads required, and all the plumbing work has been done for you.

How to use

  • Git clone or Download nRake as a Zip
  • Rename PlaceHolder app and tests to reflect your project
  • Run rake in the root of the project. This will clean, compile, template config files and run unit tests.
  • Start developing your app! How easy was that 🙂
  • Note: nRake currently uses Ruby 1.9 since IronRuby start up time was prohibitively slow. Hopefully IronRuby will get faster, and then nRake can make use of it. Also nRake uses the Albacore Gem for .NET build tasks. Documentation on Albacore tasks here.

    Also check out the IronRuby update!

Monitoring MySQL Slave Replication Status with Ruby and Cron

When offering higher levels of uptime on a web site backed by MySQL, a good approach is to set up a MySQL master-slave configuration for failover between servers. This generally works quite well, but once in a while, there is a problem or error that causes the replication to cease. The slave then ceases to process updates and gets out of sync with the master.

The script below is a quick and easy approach to monitoring the status of replication on the slave. If the slave thread or IO ceases, the slave gets more than 120 seconds behind the master, or there is an error, the script will email all the slave status information to an email address you specify to alert you that you need to log in and sort things out. I run the script from cron so that I get notified fairly soon if a problem arises.

RAILS_ENV = 'production'
ALERT_EMAIL_ADDRESS = '[email protected]'

require 'open3'
require 'socket'
require "#{File.dirname(__FILE__)}/../../config/environment.rb"

r = ActiveRecord::Base.connection.execute("show slave status").fetch_hash
unless  r["Slave_IO_Running"] == "Yes" && r["Slave_SQL_Running"] == "Yes" &&
  r["Last_Errno"] == "0" && r["Seconds_Behind_Master"].to_i < 120

    status = "*** STATUS ***\\n" + r.to_a.collect { |i| "#{i[0]}: #{i[1]}\\n" }.join
    subject = "MySQL Slave Replication Down on #{Socket.gethostname}"

    Open3.popen3("mail -s \"#{subject}\" #{ALERT_EMAIL_ADDRESS}") do |stdin, stdout, stderr|
       stdin.write(status)
    end
end

Note: This script relies on being part of a rails app to get a database connection. It would be fairly easy to modify it to include db credentials and open the connection.

HTML to PDF Conversion Plugin For Rails (A fork of wicked pdf)

Once a business web application reaches a certain size, the need often arises to generate PDFs from HTML/CSS.

Up until recently, the story around this for a MRI Rails application was not good. You could either use tools like Prawn, which require a description of the layout in a specific DSL, or pay for a tool like Prince XML which can convert from HTML, but which costs quite a bit. Those using JRuby were in a stronger position as they could use the Java PDF library called Flying Saucer.

The good news is that PDF generation for MRI Ruby is now easy and free, thanks to webkit, the open source webkit wrapper called wkhtmltopdf and mileszs’s wickedpdf plugin. I was really excited to come across this plugin and started to use it right away. However, it had a couple of issues:

  • Temp file handling caused errors when two PDFs were being generated within the same second (eg, 2 requests at almost the same time)
  • Problems generating PDF were not reported

Galdomedia forked the code and updated it to use standard Ruby temp files. This was great for ruby 1.7, but not good for Ruby 1.6 which does not allow you to set the extension on temp files (wkhtmltopdf relies on having a .html extension).

As my production servers run Ruby 1.6, I needed a different approach. My fork uses streams rather than temporary files, and adds some basic error handling and basic integration tests.

To install in a rails app:

script/plugin install git://github.com/jcrisp/wicked_pdf.git

Or clone the code from GitHub.

“Ruby for Rails” by David Black

Ruby For RailsRuby for Rails by David Black is a fun read that takes concentration but repays it with little epiphanies that explain syntax and language features that you had previously taken for granted.

The book aims to “help Rails developers achieve Ruby mastery”. The coverage of Ruby features is not complete and there are some concepts missed that I would have liked to have read more about (eg, how do instance variables work under the hood?). There are also a number of introductory chapters on Ruby and Rails and some chapters devoted to a sample Rails project (R4RMusic) which I flicked through but didn’t add much value for me (they are also a little dated). By far, the most interesting parts of the book for me were on the Ruby type system, ‘self’ in various situations and how method look up works with modules and inheritance.

An area of Ruby that I had not previously explored was adding singleton methods to instances (like what you can do in Javascript). Eg,

o = Object.new
def o.say_hi
  p "hi"
end

>> o.say_hi
"hi"

or alternatively

o = Object.new
class << o
  def say_hi
    p "hi"
  end
end

Now, the interesting thing is that this is the basis for the whole class system in Ruby!

Classes are just a special type of object, and when you add class methods, you are really adding singleton instance methods to the class object for the type.

Ie, when you do something like:

class Cars
  def self.find_all
    ...
  end

You are actually creating a new object, of type Class which has a singleton method called 'find_all'. 'self' in the code above is the Class object, so def self.xxx is adding a singleton method to it.

This also explains the alternative syntax for adding class methods:

class Cars
  class << self
    def find_all 
      ... 
    end
  end

The same thing could be done by saying:

Cars = Class.new
Cars.instance_eval { def find_all; ... end; }

In Ruby, the type and class system is not very different from the normal objects you work with every day. I find this really quite cute and internally consistent.

The way the method search path works in ruby was also nicely explained in the book. Basically, finding a method starts at the top of the list below and stops as soon as a method with a matching name is found (ie, that responds to the message sent to the object):

  • Singleton methods on the object
  • Methods defined by the object's class
  • Methods defined by modules mixed in to the class
  • Methods defined by parent class
  • Methods defined by modules mixed into parent class
  • Repeat checking parents until get to Object
  • Methods defined on Object
  • Methods defined on Kernel (module mixed into Object)

This also explains why you can always call methods like 'p' from anywhere. They are coming from Kernel which is mixed in at the top of the inheritance tree for your object. Another case of internal consistency - there's no 'special' mechanism for these seeming globals.

Overall, I enjoyed the book and would recommend anyone having a read who has worked with Ruby and Rails but would like to dig a bit deeper.

Mephisto Contact Form Plugin Moved to GitHub

Sorry the the confusion, anyone who has been checking out the the Mephisto Contact Form Plugin from the old SVN repository. The latest version with an update for Rails 2.3 is at:

http://github.com/jcrisp/mephisto_contact_form/tree/master

Spying on Instance Variables in Ruby

A little while back, a few colleagues and I were spiking a proxy concept based on extending an existing web server. We wanted to check out an instance variable (eg, @very_secret) in a framework object which did not have an accessor. In the past, we’d used send (eg, secretive_object.send :hello_private) to get at privates, but send is only for methods. We were just digging around doing some debugging, so we opened the relevant class and added a public accessor for the instance variable to see what was happening. However, we thought there must be a more elegant way to do access instance variables outside the class, and one has just come to mind (at last!):

secretive_object.instance_eval { @very_secret }

instance_eval lets us run the code block in the context of secretive_object. Ie, self == secretive_object, so we can get at all the hidden stuff.

It’s a rather different approach to other languages like C# and Java where accessing private variables and private methods are part of a reflection/introspection API.

Page 2 of 6

Powered by WordPress & Theme by Anders Norén