Releasing Textilize gem for Rails3 without C extensions

      Rails 3.X doesn't have the textilize and textilize_without_paragraph helper methods. Textilize is a gem brings back the missing method for Rails 3, and it includes the library RedCloth 3.0.4, which doesn't need to be compiled on server. Btw, The newest RedCloth is currently at 4.X though, it requires compiling C extension.

  

      The reason we need this gem is that we use :textilize at a few places in our apps, and we don't need super fast RedCloth, we just need a working version that don't force us to install C extensions on various production servers. This could be useful for bundle-package usage, where you can rely on the bundle/cache gems.

  
Related Links: 

       Sourcecode: http://github.com/kudelabs/textilize 
       RubyGem: http://rubygems.org/gems/textilize

  

Posted by Mysen 06 Jul 2012 at 04:51AM


Some Fun with Ruby Abstract Syntax Tree

For a while, I've been interested in gems that provide access to Abstract Syntax Tree (AST) representation of Ruby code, and potential possibilities they open. Just a couple days ago this interest was triggered again. The question that arose at the moment was:

  • say, we're facing somebody else's lengthy, sophisticated and rather unfamiliar code which we're planning to reuse. How do we find out where the code may be cache'ing results in instance variables - therefore, possibly, causing unplanned and undesired side effects?

Perhaps, we could convert the given piece of Ruby code into AST and then list all lines that correspond to instance variable assignment nodes... This felt like an interesting exercise so I ended up writing a little code snippet for that.

A few other possible AST uses, I thought, could be:

  • listing all methods defined in a specific file;
  • listing all method calls in a given class or method (e.g. to figure out external dependencies for refactoring or unit-testing purposes);
  • listing class variable assignments.

So, the initial script evolved into a more generic parsetree_locator.rb utility (note: requires 'ruby-parser' gem; also, only tried it on MRI Ruby 1.9).

Let me present a few examples of how the utility works.

 

Examples

Say, we have the following Ruby code in 'example.rb' file:

module M
  class C
    def meth
      @a = 2
      b = 3
    end

    def call_meth
      meth
    end

    def another_meth
      @n = 95
      call_meth
    end
  end
end

1) List all instance variable assignments - "iasgn" AST nodes:

$ ruby parsetree_locator.rb "iasgn" "example.rb"

Result:

Line nr | Module, class, method                              | Code
4:      | module M, class C#meth                             | @a = 2
13:     | module M, class C#another_meth                     | @n = 95

2) List all defined instance methods - "defn" AST nodes:

$ ruby parsetree_locator.rb "defn" example.rb

Result:

Line nr | Module, class, method                              | Code
3:      | module M, class C                                  | def meth
8:      | module M, class C                                  | def call_meth
12:     | module M, class C                                  | def another_meth

3) List all method calls - "call" nodes:

$ ruby parsetree_locator.rb "call" example.rb

Result:

Line nr | Module, class, method                              | Code
10:     | module M, class C#call_meth                        | end
15:     | module M, class C#another_meth                     | end

-- seems like the line numbers are slightly off in this case. The author of 'ruby_parser' gem mentions that it may happen; the results seem reasonable most of the time, though.

Hope that somebody else finds this utility useful as well, enjoy! parsetree_locator on GitHub

Posted by Jevgenij Solovjov 24 Oct 2011 at 07:52AM


how to solve "libglpk.so.0: cannot open shared object file" when using RVM in red hat

On linux server, we installed glpk library. then we installed rglpk gem under a gem set through RVM.

We try to use rglpk in our soft, but got this error:

libglpk.so.0: cannot open shared object file: No such file or directory -    
/home/username/.rvm/gems/ruby-1.9.2-p180@projectname/gems/rglpk-0.2.4/lib/glpk_wrapper.so

If we install the rglpk gem under system ruby paths, (by using sudo gem install rglpk), rglpk will work as expected.

From the error message, we deduce the problom is rglpk can't find the libglpk.so.0 file.

Then we checked the usr/local/lib dir, we find that file is actually there, what's wrong?

readelf -a glpk_wrapper.so

Using this command to check the content in the binary file rglpk-0.2.4/lib/glpk_wrapper.so and comparing this file the glpk_wrapper.so from system ruby, we find that library path is wrong in RVM's glpk_wrapper.so

In RMV's glpk_wrapper.so file, the library path is ruby/.rvm/gems/..../lib

In system glpk_wrapper.so file, the library path is usr/local/lib

So we make a link from RVM's library path to the correct library path usr/local/lib like this:

ln -s /usr/local/lib/libglpk.so.0 libglpk.so.0

Finally, this solved the issue, and rglpk works again!

So the reason is when we run gem install rglpk under a specific gemset under rvm, the library path indicated in glpk_wrapper.so file is wrongly configured.

Posted by 张晓峰 22 Jun 2011 at 06:00AM


installing rvm on older systems (RHEL4)

I recently had trouble installing the excellent Ruby Version Manager (rvm) onto an older production server. While bash scripting isn't my strong suite, i managed to track down the issue to this line in scripts/manage.sh:
__rvm_run "extract" "bunzip2 < '${rvm_archives_path}/$rvm_ruby_package_file.$rvm_archive_extension' | tar xf - -C ${rvm_tmp_path:-/tmp}/rvm_src_$$" "$rvm_ruby_string - #extracting $rvm_ruby_package_file to ${rvm_src_path}/$rvm_ruby_string"
Turned out that for whatever reason, this line simply didn't work in RHEL4. Luckily, it didn't take much to fix it. The first thing I did was split it into 2 lines, so I could better see where it was failing. Turns out, performing this action in 2 lines was all that needed to happen, and this worked fine.
__rvm_run "extract" "bunzip2 '${rvm_archives_path}/$rvm_ruby_package_file.$rvm_archive_extension'"
__rvm_run "extract" "tar xf ${rvm_archives_path}/$rvm_ruby_package_file.tar -C ${rvm_tmp_path:-/tmp}/rvm_src_$$" "$rvm_ruby_string - #extracting $rvm_ruby_package_file to ${rvm_src_path}/$rvm_ruby_string"
So, if rvm is failing to install ruby1.9.2 on older linux distros, this may help. I've already created a github pull request, hopefully this will get rolled into a later version of rvm. Many thanks to Wayne for this amazing package!

Posted by adevadeh 19 May 2011 at 08:09AM


Setting up rubygems without root access

Recently we had to install our rails app on a box, but we didn't have root access. The machine had ruby 1.8.6 and rubygems 0.9.6 (ouch). We can live with Ruby 1.8.6; but to run modern rails, we needed modern rubygems.

The rubygems install page has a helpful section on how to install locally without root access. Note: be sure to add export GEM_HOME=~/rubygems/gems to your .bashrc or your .bash_profile or else the next time you log in, your system gets confused again.

$ mkdir rubygems
$ cd rubygems-a.b.c
$ export GEM_HOME=~/rubygems/gems
$ ruby setup.rb --prefix=~/rubygems

Unfortunately, this didn't go as smoothly as I hoped. The result:

" `gem_original_require': no such file to load -- rubygems/exceptions"

and many other similar error messages.

The issue was that since the server installation already had an old version of rubygems installed, my local gem script was calling up the old rubygems files, but using my new GEM_HOME. A big mess.

What needs to happen is that your new gem executable needs to load your new rubygems files, and work with your new GEM_HOME. There may be a better way to do this, but I have found a workable solution for my case. It involves messing with the executable files that rubygems installs.

If you take a look at your gem executable, you'll see it is just a text file, a ruby program that executes itself.

$ cat  ~/rubygems/bin/gem

#!/usr/local/bin/ruby
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++

require 'rubygems'
require 'rubygems/gem_runner'
require 'rubygems/exceptions'

...

If you are familiar with shell scripts, you'll know that the first line (the shebang) specifies the binary to use to process the file. In this case, its #!/usr/local/bin/ruby. In general this is great. Ruby loads up the file and runs the script and magic happens. But what if the require 'rubygems' line is loading up the wrong rubygems?

We need to tell ruby where to find our custom rubygems libraries. Luckily, ruby has an option for this, -I path/to/lib. So, all we need to do is open up our gem executable and modify the shebang line to include this option.

$ vim  ~/rubygems/bin/gem

#!/usr/local/bin/ruby -I ~/rubygems/lib
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++

require 'rubygems'
require 'rubygems/gem_runner'
require 'rubygems/exceptions'

This tells the ruby interpreter to start the process with our custom path in the include path. If we have a newer version of the rubygems library there, they get required instead of the old versions. I can now install gems locally into my GEM_HOME without needing root access like so:

$ gem install mongrel

But that's not all. mongrel also installs its own executable, and when you try to run it, it will require rubygems. And yes, you guessed it, it will find the old version of rubygems and get completely confused. So again, we need to go into the executable file ~/rubygems/gems/bin/mongrel_rails and modify the shebang line.

As far as I can tell, you would need to do this for each and every gem that installs its own executable.

Update: after further consideration, using the $LOAD_PATH environment variable would probably be more robust, but my app is already installed. Perhaps you will let me know how it goes with $LOAD_PATH

Posted by adevadeh 20 Jul 2010 at 03:52AM


installing mysql gem on MacOS X Leopard

Using Rails 2.1.1, I get this warning about the mysql libraries associated with Rails:

The bundled mysql.rb driver has been removed from Rails 2.2. Please install the mysql gem and try again: gem install mysql.

As many have noted, the suggestion of `gem install mysql` doesn't seem to work well on the vanilla Leopard install with the standard MySQL pre-compiled binary. I followed lots of good advice from wonko, jlaine, hivelogic, and Seth Willits, but finally none of it worked.

Using the command from wonko:

sudo env ARCHFLAGS="-arch i386" gem install mysql -- \
  --with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib \
  --with-mysql-include=/usr/local/mysql/include

got me the ulong compile error mentioned by jlaine,. Unfortunately, jlaine's instructions didn't work for me, the manual install step doesn't seem to really install anything. I realized I had to take it step further by modifying the source of he gem itself.

In order to fix the compile error in mysql.c, it helps to understand how the gem install command works. First, gem goes online to find the correct file, then downloads the packaged .gem file to your local gem cache. Then, gem unpacks the .gem and runs extconf.rb and make/make install. From reading extconf.rb, one can see that the mysql gem uses a file called mysql.c.in as a template to build a properly configured mysql.c, which then gets compiled into the C library that we will use.

$cd /Library/Ruby/Gems/1.8/cache
$sudo gem unpack mysql-2.7.gem
$cd mysql-2.7

This gives you the source of the gem. Open mysql.c.in to add the single line we need.

#define ulong unsigned long // quick fix so that it compiles on my machine

Then we need to repack the gem, copy it to the cache folder, and install our customized version using the command above.

$sudo gem build mysql.gemspec
$sudo mv mysql-2.7.gem ../mysql-2.7-CUSTOM.gem
$sudo env ARCHFLAGS="-arch i386" gem install mysql-2.7-CUSTOM.gem -- \
  --with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib \
  --with-mysql-include=/usr/local/mysql/include

All this for one line of code...but finally:

$ gem list mysql

*** LOCAL GEMS ***

mysql (2.7)

Thankfully, most of the time we don't need to go through all this just to instal a library. This sort of thing happens rarely. But its great to know that as long as you have your command line, a good compiler, and some detective skills, you can fix many problems on your own!

Posted by adevadeh 12 Sep 2008 at 09:07PM


kudelabs public code repository

We have started a new code repository at http://github.com/kudelabs. We will be using this to host our own plugins, utility files, and example code that we wish to make public. Hopefully, something here is of use to others in the community. If you find ways to improve upon our code, we will be happy incorporate your ideas as well. We'll be posting new code when it is ready, you can use github's "follow" feature to learn about new items.

So far I am impressed with github's features, there really isn't anything quite like it. I look forward to interacting with more developers through the site.

Posted by adevadeh 02 Sep 2008 at 10:41PM


Rake task to help manage svn rename

I recently had to rename several views+controllers in a project. This is a very wearisome task since its not just a directory or a file; but directories, files, tests, fixtures, and other files that get generated by the Rails generator helpers. I searched for a little piece of code to help manage this, but didn't find anything. That may be due to the fact that earlier versions of rake did not work with arguments very well. Here is my little rake task, you can put it into a file in your lib/tasks directory and run it using:
$rake svn:rename[old_name,new_name] # notice no spaces
And here is the code:
namespace :svn do
  FILES_TO_RENAME = [ "app/views/%s",
                      "app/controllers/%s_controller.rb", 
                      "app/models/%s.rb", 
                      "test/unit/%s_test.rb", 
                      "test/functional/%s_controller_test.rb", 
                      "test/fixtures/%s.yml"]
  task :rename, :from, :to do |t, args|
    FILES_TO_RENAME.each do |s|
      from_f = s % args.from
      to_f = s % args.to
      if File.exists?(File.expand_path(from_f))
        puts "Renaming #{from_f} -> #{to_f}"
        puts %x[svn mv #{from_f} #{to_f}]
      else
        puts "Skipping #{from_f}. File not found."
      end  
    end
  end
  
end
Please leave comments if you see a way to improve this. Feel free to modify it to your needs and tell me about it.

Posted by adevadeh 13 Jun 2008 at 09:48PM


Rubob (Ruby Object Browser) 0.0.3 released

After literally a year of not finding time for finishing touches, I decided to finally just release what I have. It works fine, after all.

Rubob is based on a little tool I wrote together with Matthias Hopf in 1997 or so to play with the Java Reflection API. When I started working with Ruby almost a decade later, I realized how much easier it would be in Ruby, so I rewrote it. And then it sat there...

So what does it do?

Rubob generates a hyperlinked Web-view of your program while it runs. It can very easily be added to any existing application (one line of code).

With Rubob, every object in the system has a corresponding URL. When you access that URL, Rubob generates a Web page that contains a human readable version of the object. All instance variables are hyperlinked to the URL for their value; so you can click your way through from object to object to explore the state of your program while it's running.

Certain classes, such as Array and Hash, have a custom representation that makes their content easier to explore.

You can add your own custom representation of objects using a simple API that I'll explain when I have some time.

Here is the code.

Enjoy!

Posted by Uli 29 Apr 2008 at 09:49PM



>