Panos Matsinopoulos

Senior Software Engineer: Love Creating Software, Taking Entrepreneurial Risks, Teaching Computer Programming & Blogging here or in many other places


My Contact Details


My Projects

How to Define and Use Class-level Variables While Mixing in Modules

| Comments

There are sometimes that you might want to use class-level variables in a reusable module. How will you do that? Here is a sample ruby program that does that:

Example of Modules and class-level variables
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
require 'set'

module Cacheable
  def self.included(base)
    base.send :extend, ClassMethods
  end

  module ClassMethods
    def cached_keys
      @cached_keys ||= Set.new
    end

    def add_cached_key(key_sym)
      @cached_keys ||= Set.new
      @cached_keys.add(key_sym)
    end
  end
end

class A
  include Cacheable
end

class B
  include Cacheable
end

puts "A cached keys: #{A.cached_keys.inspect}"
puts "B cached keys: #{B.cached_keys.inspect}"

A.add_cached_key(:a)
puts "A cached keys: #{A.cached_keys.inspect}"
puts "B cached keys: #{B.cached_keys.inspect}"

B.add_cached_key(:b)
puts "A cached keys: #{A.cached_keys.inspect}"
puts "B cached keys: #{B.cached_keys.inspect}"

A.add_cached_key(:aa)
puts "A cached keys: #{A.cached_keys.inspect}"
puts "B cached keys: #{B.cached_keys.inspect}"

B.add_cached_key(:bb)
puts "A cached keys: #{A.cached_keys.inspect}"
puts "B cached keys: #{B.cached_keys.inspect}"

If you run the above ruby script, you will get the following output:

Output of running the above ruby script
1
2
3
4
5
6
7
8
9
10
A cached keys: #<Set: {}>
B cached keys: #<Set: {}>
A cached keys: #<Set: {:a}>
B cached keys: #<Set: {}>
A cached keys: #<Set: {:a}>
B cached keys: #<Set: {:b}>
A cached keys: #<Set: {:aa, :a}>
B cached keys: #<Set: {:b}>
A cached keys: #<Set: {:aa, :a}>
B cached keys: #<Set: {:bb, :b}>

In the above example, we keep a class level Set of symbols (@cached_keys). We want every class that mixes in Cacheable to have its own instance of that Set.

My Solr Journey - Session 001

| Comments

Why do I take this Journey?

I have been using Solr the last two years for quite some projects. My work was always done using sunspot (via sunspot_rails when one has Rails application), a gem that is a client library for Solr.

You need to know few things about Solr, when using sunspot to access it and do most of the things. sunspot is a fantastic gem and relieves you from huge amounts of work when storing data in a Solr database.

However, there are times that I felt that I needed to know more. For example, when I was searching for University of Athens and I got no results, but I knew that my documents had all or any of the words “University”, “of”, “Athens” in their body, or, even worse, there were also documents that were having the whole phrase “University of Athens” in their body. Or I wanted to query with parts of words, or parts of e-mails, and still I was not getting any results. You can see how I ended up solving these problems reading these two: 1) Why Sunspot Solr does not bring results when I include “of” word in search query? 2) How can I set Sunspot to search for sequences of characters instead of words?

Hence, I decided to take a journey to Solr. And this will be a registration of my steps to this journey. Understanding how Solr works, will make me manage better what I can do and achieve with sunspot too.

And here we go

First steps

Summary

One cannot be but extremely impressed of the features and capabilities of Solr. I believe that I will use to replace many of my MySQL stores that are only used for querying.

(Next steps will soon follow)

Executing Migration Commands From Rails Console

| Comments

Did you know that you can execute migration commands from rails console? Assume that you want to change the column ‘name’ of the ‘Product’ model, to have a limit of 32 characters and set it to not null. Here is what you can do:

Example of ActiveRecord Migration run from Rails Console
1
2
3
4
5
6
$ rails c
> ActiveRecord::Migration.change_column :products, :name, :string, :limit => 32, :null => false
-- change_column(:products, :name, :string, {:limit=>32})
(38.1ms)  ALTER TABLE `products` CHANGE `name` `name` varchar(32) NOT NULL
-> 0.0396s
=> nil

Capistrano - Shared Directories Among Releases

| Comments

Capistrano is a great tool for deploying Ruby on Rails applications on remote server machines. If you have ever used it, you may already know that it creates new directory structures for each new release that it realizes and sets “current” to point to the latest one.

This is very fine, but there are cases in your application that you might want to share the same directory data among releases. You can declare in your “deploy.rb” file the directories that will be shared among your releases. By default, the directories “log”, “public/system” and “tmp/pids” are already shared. Hence, you do not have to do anything for them. But, if, for example, you want to share the “my_custom_data” directory that you have inside your application structure, you need to add the following line inside your “deploy.rb” file:

Add this line to your deploy file
1
set :shared_children, fetch(:shared_children) + ["my_custom_data"]

This will create a link to “shared/my_custom_data” folder by executing the following command automatically:

Create a link to your custom shared folder
1
ln   -s  /home/<my_app>/<deployment_dir>/shared/my_custom_data   /home/<my_app>/<deployment_dir>/current/my_custom_data

Please, note that my_custom_data should pre-exist while you are doing the deployment. But, bundle exec cap setup will create shared folders anyway for you the first time you setup your servers.

Testing - Asserting Template and Layout

| Comments

I consider testing one of the most important phase in application development and Rails does a very good job on that. However, testing documentation on Rails Guides is still work under development.

Here is a short tutorial on how you can test that a reponse has rendered the correct template and the correct layout.

If you want to make sure that the response rendered the correct template and layout, you can use the assert_template method:

assert_template usage
1
2
3
4
5
test "index should render correct template and layout" do
  get :index
  assert_template :index
  assert_template :layout => "layouts/application"
end

Note that you cannot test for template and layout at the same time, with one call to assert_template method. Also, for the layout test, you can give a regular expression instead of a string, but using the string, makes things clearer. On the other hand, you have to include the “layouts” directory name even if you save your layout file in this standard layout directory. Hence,

This will not work
1
assert_template :layout => "application"

will not work.

Gotcha: Watch out if your view renders any partial

If your view renders any partial, when asserting for the layout, you have to assert for the partial at the same time. Otherwise, assertion will fail.

Hence:

Correct way to assert for the layout
1
2
3
4
test "new should render correct layout" do
  get :new
  assert_template :layout => "layouts/application", :partial => "_form"
end

is the correct way to assert for the layout when the view renders a partial with name_form. Omitting the :partial key in your assert_template call will complain.

Ruby Style Guide

| Comments

This is a very good guide on how one should style its Ruby code. I am following this since I started Ruby and I suggest that everybody does the same.

One extra on usage of {…} vs do…end blocks can be found here (Weirich Convention).

Maze Implementaion in Ruby

| Comments

This is an implementation of a Maze algorithm to find the path from start to goal in between the walls of a maze.

Read the details here.

Octopus Problem With Rake

| Comments

This week I have decided to use octopus, a fantastic gem for realizing replication or sharding. I have already implemented MySQL Replication (Master / Slave) and I wanted to have my Ruby on Rails application actually use it!

This is my github project: Octopus Replication Example

Your comments are welcome!

Rails and Test Unit Bug on Counting Passed Tests

| Comments

During the weekend I have discovered a bug on Rails activesupport gem. The truth is that it has already been reported to Rails. It is the issue https://github.com/rails/rails/pull/2472.

You can see my detailed answer here: http://stackoverflow.com/questions/7706487/rails-tests-showing-0-passed-when-all-pass/7939497#7939497

Use the gist that is referred there until the bug is fixed.

As always, your comments are welcome.