Archive for the '/dev/ruby' Category

A Method That Knows Its Own Name: this_method()

I realize this is the second mailing list-mining for content this week but this was too cool to not mention. Over in Ruby Forum in using the current method name within current method Aleks Kissinger, Robert Klemme, and Matt Todd hashed out a way for methods in Ruby 1.8 to know their own identity.

To jump to the end, the final solution is:

module Kernel
private
   def this_method
     caller[0] =~ /`([^']*)’/ and $1
   end
end

As an example:

class TestClass
   def this_methods_name
      puts this_method
   end
end

t = TestClass.new
t.this_methods_name

Pretty cool stuff, that.

No Comments »

chris on January 14th 2008 in /dev/ruby

Ruby 1.9: Not For Rails

Do NOT install or upgrade to Ruby 1.9 if you’re using Ruby for Rails development.

There, that warning ought to suffice.

On Dec. 25 Matz announced that a development release of Ruby 1.9 was available in which the Ruby 1.9 spec has been frozen:

We are happy to announce of the release of the 1.9.0 the development
release.

We hope this helps you to enjoy hacking. Happy Holidays.

matz.

However, Ruby 1.9.0 is not a drop-in replacement for Ruby 1.8.* with more good stuff inside, many fundamentals have changed, often in incompatible ways. As Dave “PickAxe” Thomas notes:

This is a development release, not a production release. It has known bugs, and there’ll be more to come.

It contains several incompatible changes (block parameters are now block-local, String is no longer Enumerable, “cat”[1] now returns “a”, rather than 65)

It is more rigorous that 1.8 when it comes to detecting invalid code. For example, 1.8 accepts /[^\x00-\xa0]/u, while 1.9 complains of invalid multibyte escape

the likes of which are guaranteed to break either Rails, some critical gem, a required plugin or your own code. Honestly, it’s guaranteed.

As example from the Rails list:

just now i installed ruby 1.9 and rails 2.0.2 on it. when i create new rails application

username@ubuntu7.04:~/project$ rails app
can’t convert Enumerable::Enumerator into Array

and

Agreed. I just upgraded to 1.9 and found all my applications totally
hosed. I had to delete 1.9 and reinstall 1.8.6, along with Ruby Gems (on
Leopard).

I’ll be waiting for the official announcement of compatibility on the
Rails blog.

and from Rick DeNatale:

I just answered a post from someone on the TextMate forum who
installed Ruby1.9 as ruby. Now he gets a syntax error inside textmate
when he tries to run a ruby program, since Textmate uses ruby
internally, and some of that code ran into one of the syntax
incompatibilities.

Anyway, you get the idea.

If you really want to play around with Ruby 1.9, perhaps to help with the testing or just to get an idea of what cool stuff will be landing in Ruby 2.0, Dave Thomas’ post, cited above, provides great details in just how to do that.

Congrats to Matz and all the ruby-core team on 1.9.

Update: Should you need even more proof of the current “dev” state of Ruby 1.9.0, a fairly significant string encoding bug was bound found, isolated and fixed just four days after release.

No Comments »

chris on December 30th 2007 in /dev/rails, /dev/ruby

Ruby: Can a Function Know It’s Own Source File?

I got to wondering this weekend: can a function know about it’s own source file in Ruby? The reason I was wondering this is because I’ve found that when working on someone else’s Ruby source code the ease with which mixins can be made sometimes leads to code that’s very difficult to trace.

Stack a few layers of inheritance together, stick some mixins into each level and then try and locate the original location of my_obj.coerce()… I tend to have to resort to TextMate’s global Find to search through the whole project (and woe is me if it contains multiple coerce() functions in different files). True story, that example.

What I’d like, and haven’t yet been able to discern a means to do, is either:

Kernel::source_file( my_obj.coerce )

or

my_obj.coerce.source_file()

or something along those lines which would spit back:

/var/src/my_proj/modules/coercion_functions.rb

Does this already exist? Am I missing something trivial?

No Comments »

chris on November 26th 2007 in /dev/ruby

Ruby: Converting an Array to a Hash

Converting a hash into an array in Ruby is easy but what about an array into a hash? This code does the trick quite nicely, and if you don't want to actually extend the Array class this does as well:

RUBY:
  1. a = ["cat","dog","monkey"]
  2. h = Hash[*a.collect { |v| [a.index(v), v] }.flatten]

Update: Speaking of mucking about with arrays, ArraySugar adds a few nice shortcuts to arrays. I like the select syntax (but it seems like overkill to install this as a gem).

No Comments »

chris on October 7th 2007 in /dev/ruby

The Power of rake

rake is one of those little things about Ruby on Rails that I suspect most of take completely for granted, running the odd rake tast without really ever thinking much about it. Turns out rake is pretty damned cool.

Gregg over on Rails Envy has written a very nice intro to rake in Ruby on Rails Rake Tutorial (aka. How rake turned me into an alchoholic) :

In this article we're going to discover why Rake was created, and how it can help our Rails applications. By the end you should be able to write your own tasks, and learn how to get piss drunk using rake in no less then three steps.

He's written well enough that by about midway down the article I was already thinking of ways to use rake to do some of the unpleasant maintenance tasks every site needs that I was consequently putting off thinking about. rake: not bad at all.

No Comments »

chris on June 12th 2007 in /dev/rails, /dev/ruby

Using a hash to count incrementally

A hash is great for keeping track of counts of things if you we already know what those things are, but how to add a new thing without a bunch of cumbersome code? Use fetch():

RUBY:
  1. count[item] = count.fetch(item, 0) + 1

If item already exists then it will add 1 to it. If item doesn't exist, it'll initialize it with a value of 0 and then add 1 to it.

2 Comments »

chris on June 1st 2007 in /dev/ruby

More Trivial Scripting with Ruby

Last Friday, in Trivial Scripting with Ruby on O'Reilly Ruby, Gregory Brown demonstrated a two-line example of the ease with which simple utility scripts can be created from Ruby. In his case a script that takes a filepath and returns the contents with all HTML entities escaped.

I like it, but I don't have any use for this operating on a per-file basis. More useful to me is being able to pass in the HTML text via command line args:

RUBY:
  1. #!/usr/bin/env ruby
  2.  
  3. require "cgi"
  4. ARGV.each { |x| puts CGI.escapeHTML( x ) }

I saved this as esc.rb. To use:

Sagarmatha:~/Documents/utilityscripts chris$ ./esc.rb "<em>Hello & World</em>"
&lt;em&gt;Hello &amp; World&lt;/em&gt;

2 Comments »

chris on April 19th 2007 in /dev/ruby

Updating MySQL Gem to 2.7

While updating my installed gems this evening I ran into an issue with the mysql-2.7 gem:

ERROR: While executing gem ... (Gem::Installer::ExtensionBuildError)
ERROR: Failed to build gem native extension.

ruby extconf.rb update
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... no
checking for mysql_query() in -lmysqlclient... no

The solution was to explicitly tell gem where the local MySQL install is:

Sagarmatha:~ chris$ which mysql
/usr/local/mysql/bin/mysql

Sagarmatha:~ chris$ sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql

Caveat: Note the double -- between mysql and --with. That's not a typo (though it may look like a single dash in this page in some browsers).

4 Comments »

chris on April 19th 2007 in /dev/ruby

Ruby Jobs

Looking for a job working with Ruby and/or Rails?

http://jobs.rubynow.com/

Even better, there's an RSS feed: http://jobs.rubynow.com/rss/feed.xml

(Note to my current co-workers: no worries, I'm not looking, honest)

(Thanks Sam!)

No Comments »

chris on April 9th 2007 in /dev/rails, /dev/ruby

English-friendly timespan in Rails

Awhile ago I was looking for a function that would convert a number of seconds into a human-readable timespan string. For instance: convert 86400 into 1 day and 172800 into 2 days, accomodating intervals ranging from weeks to minutes.

I didn't find one. Instead, this is what I came up with this, which at its fanciest will output something like 2 days, 14 hours and 15 mins.

RUBY:
  1. # Takes a period of time in seconds and returns it in human-readable form (down to minutes)
  2. def time_period_to_s time_period       
  3.   out_str = ''
  4.      
  5.   interval_array = [ [:weeks, 604800], [:days, 86400], [:hours, 3600], [:mins, 60] ]
  6.   interval_array.each do |sub|
  7.     if time_period>= sub[1] then
  8.       time_val, time_period = time_period.divmod( sub[1] )
  9.          
  10.       time_val == 1 ? name = sub[0].to_s.singularize : name = sub[0].to_s
  11.            
  12.       ( sub[0] != :mins ? out_str += ", " : out_str += " and " ) if out_str != ''
  13.       out_str += time_val.to_s + " #{name}"
  14.     end
  15.   end
  16.  
  17.   return out_str 
  18. end

Obviously it's hard-coded only to support english and ignores seconds (too fine-grained for me) but over-coming either of those limitations should be fairly straight-forward.

Update: I terminated the upper value at weeks because things get complicated when we get to months. We can all agree that a day is 24 hours, a week is 7 days, but how long is a month? Not four weeks, not five weeks.... Predictability dies at months, where the actual timespan becomes relevant, and that's more work than is worthwhile at this point. Feel free to embrace and extend :)

2 Comments »

chris on April 4th 2007 in /dev/rails, /dev/ruby