Friday, May 28, 2010

Ruby's origins - a find



Ruby is a pure Object-Oriented programming language. Everything in Ruby is objects, even classes. Amazing? Let's see why:

irb> 'hello'.class
=> String
irb> String.class
=> Class
irb> Array.class
=> Class
irb> Class.class
=> Class

See even further:

irb> Class.superclass
=> Module
irb> Module.superclass
=> Object
irb> Object.superclass
=> nil

irb> Module.class
=> Class
irb> Object.class
=> Class

So all classes are objects of class "Class". String, Array,.. are instances of class "Class".
Module and Object are super classes of "Class" but also instances of "Class"!!!

Tuesday, May 25, 2010

Install adva-cms on Windows

Adva-cms is an open source CMS (Content Management System) platform based on Ruby on Rails. Installing adva on Windows could be a bit tough. Follow is the steps I've tried to get passed:

1. Make sure you already installed ImageMagick and some gems adva requires

2. Just follow adva's installation guide:

# Create your app
rails my-app
cd my-app
rm public/index.html

# Prepare the config/environment.rb and remove the public/index.html
# in config/environment.rb make sure you have:
require File.join(File.dirname(__FILE__), 'boot')
require File.join(File.dirname(__FILE__), '../vendor/adva/engines/adva_cms/boot') # this line

# You *must* use Rails' old routing recognition/generation mode in order for adva-cms to work correctly:
# in config/initializers/new_rails_defaults.rb set:
ActionController::Routing.generate_best_match = true

# Clone the adva-cms ( this might take a bit, grab a coffee meanwhile :) )
git clone git://github.com/svenfuchs/adva_cms.git vendor/adva # or use: git submodule add ...

# Install the core engines and copy the assets
rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks # install adva-cms to vendor/plugins/
rake adva:assets:install # symlinks plugin assets to public/

...and get this error

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks
(in d:/Document/Projects/AdvaCMS/adva3)
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac, adva_user
rake aborted!
unknown file type: ../adva/engines/adva_activity

(See full trace by running task with --trace)

Let's trace to see why it failed:

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks --trace
(in d:/Document/Projects/AdvaCMS/adva3)
** Invoke adva:install:core (first_time)
** Execute adva:install:core
** Invoke adva:install (first_time)
** Execute adva:install
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac, adva_user
rake aborted!
unknown file type: ../adva/engines/adva_activity
c:/Ruby/lib/ruby/1.8/fileutils.rb:1256:in `copy'
c:/Ruby/lib/ruby/1.8/fileutils.rb:451:in `copy_entry'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1325:in `traverse'
c:/Ruby/lib/ruby/1.8/fileutils.rb:448:in `copy_entry'
c:/Ruby/lib/ruby/1.8/fileutils.rb:423:in `cp_r'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1396:in `fu_each_src_dest'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1405:in `fu_each_src_dest0'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1403:in `each'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1403:in `fu_each_src_dest0'
c:/Ruby/lib/ruby/1.8/fileutils.rb:1394:in `fu_each_src_dest'
c:/Ruby/lib/ruby/1.8/fileutils.rb:422:in `cp_r'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:139:in install'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:126:in `send'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:126:in `perform'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:119:in `each'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:119:in `perform'
d:/Document/Projects/AdvaCMS/adva3/vendor/adva/engines/adva_cms/lib/tasks/adva_cms.rake:35

...so there're something wrong in adva_cms.rake file. It took me a while to understand how this file does things and found the lines that caused bugs:

def source(type, subdir = nil)
"../adva/#{type}" + (subdir ? "/#{subdir}" : '')
end

...so maybe this relative path causes confusing. Let's make it full:

def source(type, subdir = nil)
"#{Rails.root}/vendor/adva/#{type}" + (subdir ? "/#{subdir}" : '')
end

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks
(in d:/Document/Projects/AdvaCMS/adva3)
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac
, adva_user
installing plugins: adva_cells
c:/Ruby/bin/rake: No such file or directory - which convert
rake aborted!
private method `chomp' called for nil:NilClass

now the engines installed ok, but there's still errors in installing plugins. It caused by paperclip initialization code that uses 'which' command to find path to 'convert' which is a tool provided by paperclip gem but 'which' command does not exist on Windows

d:/Document/Projects/AdvaCMS/adva3/vendor/plugins/adva_cms/config/initializers/p
aperclip.rb:1

Paperclip.options[:command_path] = %x[which convert].chomp.gsub(/convert/, '')

...so just go to ../vendor/adva/engines/adva_cms/config/initializers/paperclip.rb and remove 'which'

Paperclip.options[:command_path] = %x[convert].chomp.gsub(/convert/, '')

then adva's core installation gets passed!

$ rake adva:install:core -R vendor/adva/engines/adva_cms/lib/tasks
(in d:/Document/Projects/AdvaCMS/adva3)
installing engines: adva_activity, adva_blog, adva_cms, adva_comments, adva_rbac
, adva_user
installing plugins: adva_cells
copied 33 migrations to db/migrate
copied 33 migrations to db/migrate/app
copied 33 migrations to db/migrate
== CreateActivitiesTable: migrating ==========================================
-- create_table(:activities, {:force=>true})
-> 0.0050s
== CreateActivitiesTable: migrated (0.0060s) =================================
...

3. Next, install adva's assets and run it up

$ rake adva:assets:install -R vendor/adva/engines/adva_cms/lib/tasks
$ script/server

...and this is what I've got


Monday, May 17, 2010

An issue with Rspec on Windows



Rspec is a very popular test framework used to test Rails application. I have tried to install and use it for my Rails projects on Windows. It raised a bug when I ran tests:
c:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:440:in load_missing_constant': uninitialized constant RbReadline::Encoding (NameError)
from c:/Ruby/lib/ruby/site_ruby/1.8/rbreadline.rb:4404 
I traced back and found these causing lines:
   if defined? ''.getbyte
      @encoding = "X"      # ruby 1.9.x or greater
      @encoding_name = Encoding.default_external.to_s
   end
It seems the Rspec uses Ruby Readline library for its command-line interface. It defined getbyte that uses Encoding module which hasn't been defined in this Ruby package on Windows. I then commented out the line using Encoding module and the bug get fixed...
   if defined? ''.getbyte
      @encoding = "X"      # ruby 1.9.x or greater
      # @encoding_name = Encoding.default_external.to_s
   end
It's not common to pass over the issue by this way but hopefully it still works fine in my case.