263 Posts in Category 'Programming' RSS

Ruby Fractals

This week's Ruby quiz is about fractals. I had some fun with it today. I uploaded a bunch of PNGs of fractals I made in the spirit of that quiz. I'll have to send in my code if I ever get a minute to clean it up. Or maybe not; someone else in the official thread had an idea very similar to mine, and did his version first. I ganked some of his patterns too for testing. Didn't look at his code though.

It's my first try using RMagick. It's not at all hard to use. It took me a while to figure out how to shift the axes so that 0,0 was in the middle of the image instead of the top left though. Enormous APIs are the bane of my existence.

May 27, 2007 @ 3:02 PM PDT
Cateogory: Programming
Tags: Ruby

Fun with iterators

Given this:

text = 'blah blah ##REPLACE1 ##REPLACE2 ##REPLACE3 blah blah'

repl = {
    '##REPLACE1' => 'foo',
    '##REPLACE2' => 'bar',
    '##REPLACE3' => 'foobar'
}

Which of these works as expected?

text.scan(/##\w+/) do |tag|
    text.gsub!(tag, repl[tag])
end

or

text.scan(/##\w+/).each do |tag|
    text.gsub!(tag, repl[tag])
end

The answer (as perhaps expected) is the second one. Both use a C function scan_once which as expected iterates through the string position-by-position. The second version collects all the matches into an array and lets you iterate over that; the first keeps iterating over the string itself, and if you edit the string, the index that scan_once has been using will point to a different place than it should.

It's probably in general not well-defined what happens when you start editing a string you're iterating through. Well, it's possibly well-defined but probably not what you'd ever want. I can't recall reading anything about it in Ruby but I can't imagine any way of anything good coming from fiddling with the guts of things as you iterate over them. I learned this lesson yesterday, the fun way.

May 11, 2007 @ 4:54 AM PDT
Cateogory: Programming
Tags: Ruby

Firefox + vim

In about:config change view_source.editor.external to true and you can pick a "View Page Source" editor via view_source.editor.path. /usr/bin/gvim for example. Wish I'd have discovered that a couple years ago.

May 09, 2007 @ 10:39 AM PDT
Cateogory: Programming
Tags: Firefox, Vim

Darn you, failglob

I turned on bash_completition today. Couldn't quite remember why I had it turned off. I quickly realized though. bash would fail on any filename with a square-bracket in it. It looks something like this:

~ $ touch 'test [1]'
~ $ ls<I HIT TAB HERE> bash: no match: test [1]
~ $

In other words, hitting TAB to tab-complete filenames would dump me back to a command prompt giving me that unhelpful error message, and I'd have to start the whole command over.

The problem was that I had this in my ~/.bashrc:

shopt -s failglob

I can't for the life of me remember why that was in my .bashrc. Clearly it wasn't doing anything I never had any use for, because this is the first time I got this "bash: no match" error. Removing that line makes bash_completion work again though, so all is well.

This was a nightmare to debug too. Google was totally useless. I tracked it down to the _filedir function in /etc/bash_completition, and then it was trial-and-error. Next time I'm going to start off loading a clean login environment before I bother checking the system scripts for things. I did also learn that set -v in a bash script makes it dump every line it executes to STDIN as it's executing them.

May 05, 2007 @ 1:14 PM PDT
Cateogory: Programming

Class instance variables

Previously I rambled about Ruby singleton classes. It turns out class instance variables are apparently actually recommended over class variables by many people. One big reason is that class variables are shared between classes and subclasses, which can lead to ugly behavior, but class instance variables are not. A google search leads to plenty of other people talking about this (example).

Today I saw on Ruby Forum some more discussion of class instance variables and it seems like a place for potential evil silent bugs. Look at this:

class A
    attr_reader :x
    def initialize
        @x = 1
    end
    def A.test
        @x = 2
    end
end

inst = A.new 
A.test
puts inst.x

This obviously prints "1", not "2". The reason is A.test operates in the context of the class, so you're really setting a A's class instance variable @x to 2, not the normal instance variable @x. But at a glance, in a program of significant size, I'm not sure how easy this would be to spot. I remember Java for example throws a fit if you try to access instance variables from inside a static method. Ruby silently allows it, which is a good thing in that it lets you do neat stuff with class instance variables, but it seems also like an easy way to create hard-to-identify bugs. I guess that argument applies to Ruby as a whole though.

May 02, 2007 @ 4:02 AM PDT
Cateogory: Programming
Tags: Ruby, Java

Rails impressions

So after a weekend of Ruby on Rails'ing, as expected, I do really love it. I hit a couple "gotchas" but nothing show-stopping.

Rails does so many things automatically that at times you can't keep track of it. This is not fun when it comes time to track down a bug when your script crashes.

I have yet to really understand start-to-finish what goes on when Rails handles a request. I know that Apache (via htaccess rewrites in my case) or your server of choice pipes incoming requests to a Rails dispatcher CGI script. Then it somehow knows to parse the URL and route it according to the routes you set up. Then Rails auto-requires a whole bunch of files from a whole bunch of directories, apparently selected via some sort of magic hand-waving algorithm. Then control is passed to one of your controller files, which potentially loads a dizzying array of templates in the form of views and layouts and partials, and has access to all kinds of things in the helpers and lib directories.

When working in the various model/controller/view files, via some magic, lots of things are visible that probably wouldn't be in a normal Ruby script. You set an instance variable in one place and then magically it's visible in all kinds of other places. Lots of your user-defined classes are visible everywhere with no need to require any of their source files.

I've also already been bitten by accidental collisions with some of Ruby's naming conventions. Any column called "type" in any table will cause horrible and non-intuitive breakage, because Ruby by default uses a column called "type" for some kind of funky table inheritance scheme. Rails also expects table names to be plurals of model names, which leads to some fun when you have a model called "Armor" and you have to make a table called "armors"(?). You can inform the Rails Inflector that the plural of "armor" is "armor", but it's kind of annoying to have to. Those are not the only such problems I've run into, either; namespace pollution and naming convention oddness in Rails is everywhere. But at least in a great many cases Rails give you a way to override or ignore the defaults.

(Note to self: Wordpress chokes on any post containing the text ".htaccess". Why?)

April 30, 2007 @ 7:42 AM PDT
Cateogory: Programming
Tags: Ruby

Vim Ruby

Note to self: vim-ruby's matchit support is delicious. It lets you bounce on the % key to switch between class/end and def/end and if/else/end.

For whatever reason, at work when I installed Vim, matchit was installed by default along with Vim, but you have to manually copy it to the proper directory and build the help file for it yourself before it will work. There are instructions for how to do so at the end of ruby.vim in Vim's standard vim70/ftplugin directory.

April 25, 2007 @ 4:11 PM PDT
Cateogory: Programming
Tags: Ruby, Vim

Ruby, Rails, etc.

I tried out Ruby on Rails for the first time today. My spare time (what little remains of it) has been divided between playing with my websites, and playing with Ruby. So I figured why not combine the two.

It's somewhat infuriating when I can start from scratch and make something in 15 minutes in Rails that works as well as the huge mess of PHP crap that it took me over a week to write. My previous web host didn't have Ruby, so I was forced to use PHP by necessity. PHP4, of course. Blech. Is there anyone on this planet who uses PHP by choice?

I briefly toyed with the idea of using Smarty. It seems like a nice templating system, with its only weakness being that you have to use PHP to use it.

On a different topic, this week's Ruby Quiz was amusing. The problem is essentially to split a string in every possible way (with varying split length, with some upper bounds on split length), transform the parts, recombine them, and then print or process the result. A recursive solution is very straightforward: split the string into a little left part and a big leftover right part, transform the left part, then recursively process the right part in the same way. I wrote up a solution that's about 20 lines long. But it's slow as heck.

Reading other people's solutions, I noticed a neat thing about recursion in Ruby. There are two different ways of doing this recursively. One way (the slow way and memory-intensive way, the way I did it) is to recurse all the way to the base case (run out of leftovers to process), leaving your transformed bits of string scattered all over your call stack. Then return all the parts back up the call stack putting them together as you go. When you've hit the very top of the stack again, you'll have a huge accumulated list (array) of all the results.

But another way is to pass the partly-processed and unprocessed parts of the string both down the call stack as parameters in your method; each method call eats a bit of the unprocessed part and adds a bit to the processed part and then both are passed along again. The base case is once your unprocessed part is empty. If you also pass a Ruby block along as you recurse, then when you hit the bottom of the call stack, you can yield your accumulated fully-processed result to the block. This way you don't have to collect all the results into an array before returning them. You can yield the results as soon as you compute them, one-by-one. I thought it was neat.

April 25, 2007 @ 3:55 PM PDT
Cateogory: Programming
Tags: PHP, Ruby

Ruby Quiz

I always enjoy Ruby Quiz. The problems are short enough to be doable in a day but hard enough to make you think, usually.

The one for this week was the first I attempted myself. I didn't submit it because I'm very late and everyone else's solutions are similar to mine. And I'm also a bit self-conscious when in the presence of people who are much better coders than I am. But it was fun to do. Only took an hour or two (I lost track of time).

I've picked up a couple neat tricks over the weeks / months of reading that place. I had to write a recursive algorithm for generating permutations of an array, and somehow I must've learned it without realizing because the one I wrote / "figured out" myself is almost identical to some of the ones used by other people on that site.

I do too much talking about programming and not enough programming. (Thus making this post somewhat ironic.) Grinding out a bunch of code is the only real way to learn or get any better.

April 09, 2007 @ 2:44 PM PDT
Cateogory: Programming
Tags: Ruby

Ruby singleton classes

I was writing some Ruby and I must've had my head stuck in Java, because I wrote something like this:

class Test1
    @x = 1
end

That is very different from this:

class Test2
    def initialize
        @x = 1
    end
end

In the latter case I made a normal instance variable which any object that is_a? Test2 can access. In the former case I made an instance variable of Test1 itself. Classes in Ruby are Objects like any other; I gave the Test1 object itself an instance variable. So:

Test1.new.instance_variables # => []
Test2.new.instance_variables # => ["@x"]

Chapter 24 of the Pickaxe book talks about singleton classes. You can edit objects (add methods and instance variables etc.) on a per-object basis rather than a per-class basis. You can do this because Ruby makes a "virtual" singleton class, makes that singleton class the direct class of your object, and makes your object's original class the superclass of this new singleton class. That way the object's original class is untouched and your meddling doesn't affect any other objects of the same class.

In Test1 above this is what I did. Ruby made a new singleton class, which the Pickaxe calls Test1, and made an instance variable @x in it. That instance variable is then accessible as a part of the Test1 object itself. If it were theoretically possible to instantiate another object of type Test1', it would presumably have a @x too, but this isn't possible.

So say I want to access this @x that belongs to Test1. The Pickaxe tells you how. In general, if you have an object and you want to access an instance variable of it, you define a "getter" method in your object's class that returns the variable's value. You can use the shortcut attr_reader to do this.

So if you want to access an instance variable of Test1 itself, you need to define a method in Test1's class (i.e. the singleton class, Test1'). The Pickaxe says to do this:

class Test1
    class << self
        attr_reader :x
    end
end

Test1.x  # =>; 1

It makes perfect sense that you can also do it this way:

class << Test1
    attr_reader :x
end

Test1.x  # => 1

The Pickaxe gives a couple reasons why you might want to do this kind of thing. But I'm going to go ahead and label it "black magic" and stay away from it, I think.

March 22, 2007 @ 3:26 AM PDT
Cateogory: Programming
Tags: Ruby