Posted by Nick Sieger
Tue, 30 May 2006 16:57:00 GMT
Having trouble getting IRB to use a .irbrc file on Windows? The following seems to work:
- Create the .irbrc file in your
%USERPROFILE%
directory.
- Create an environment variable in the System Properties->Advanced Tab->Environment Variables area called
HOME
and set it to %USERPROFILE%
.
An alternate approach is to create an environment variable called IRBRC
and set it to the full path of the .irbrc file.
Perhaps IRB should be updated to look in %USERPROFILE%
on Windows?
Plug: for handy .irbrc contents refer to this previous post.
Posted in ruby | Tags ruby | 1 comment | no trackbacks
Posted by Nick Sieger
Fri, 26 May 2006 03:32:00 GMT
Before my big blog drought at the beginning of the year, I had an
entry queued up talking about some success I’d experienced with Rails.
A lot in the Rails world has progressed since then, but I still think
the story is worth documenting. Also, the code to generate a PDF of
mailing labels may be useful to somebody out there.
I’ve had some Rails success lately building a home-use mailing list
manager/rolodex application. There are plenty of ways that such a
list could be maintained without resorting to a full web application
framework such as Rails, but what the heck! The mailing list
started life as an MS Access database; after my work computer was
re-imaged I no longer had “access to Access” so it had a temporary
layover in an Excel spreadsheet. Within the past couple of months I
had moved it to a MySQL database as a way to nurture my fledgling
Rails efforts.
Ok, so nothing real special so far, except that in order to print
mailing labels (one of the primary reasons for keeping such a list)
I’d have to export the names to a .csv file and do a mail merge with
Word. Until the most recent mailing.
On a Saturday night I had the brainstorm to use Austin Ziegler’s
PDF::Writer library to create a printable PDF directly from
the Rails app, thus skipping the need to go through the mail merge
rigamarole. Only a couple of hours of effort later, I had my
mother-in-law’s Christmas mailing list printed out! Anyone who has
ever done a mail merge with Word knows that clicking a single link
to create the printable versions of the mailing labels is a huge
improvement in usability. And finally, no MS bits were harmed in
the production of this mailing!
My starting point in building the code to generate PDFs was this page
in the Rails wiki. I decided to use the method that
describes installing an “rpdf” template handler. Nowadays, you may as
well use Josh Charles’ Rails PDF plugin, but for posterity
I’ve packaged up my effort as a simple plugin as well
(install into an existing Rails application with ./script/plugin
install http://svn.caldersphere.net/svn/main/plugins/pdfrender
).
With the plugin in place, all that’s necessary is a controller method
to set up the data for the view, and the view code itself. The
controller is as straightforward as you’d expect:
class AddressController < ApplicationController
def pdf
@addresses = Address.find(:all, :order => 'last_name, first_name')
render :layout => false
end
end
The view code is a little more hairy but with a little thought the
dimensioning and layout code could easily be DRY’d out.
FONT = "Times-Roman"
FONT_SIZE = 12
COLS = 3
LABELS_PER_PAGE = 30
LABELS_PER_COL = 10
MARG_X = pdf.in2pts 0.19
MARG_Y = pdf.in2pts 0.5
CELL_Y = pdf.in2pts 1
CELL_X = pdf.in2pts 2.63
COL_PAD_X = pdf.in2pts 0.19
COL1_X = MARG_X
COL2_X = COL1_X + CELL_X + COL_PAD_X
COL3_X = COL2_X + CELL_X + COL_PAD_X
CELL_PAD_X = pdf.in2pts 0.13
CELL_PAD_Y = pdf.in2pts 0.25
CELL_LINE_Y = FONT_SIZE + 2
def cell_x(col)
[COL1_X, COL2_X, COL3_X][col] + CELL_PAD_X
end
def cell_y(row, line)
MARG_Y + ((LABELS_PER_COL - row) * CELL_Y) - CELL_PAD_Y - (line * CELL_LINE_Y)
end
def add_label(row, col, addr, pdf)
if addr
pdf.add_text_wrap(cell_x(col), cell_y(row, 0), CELL_X, addr.name, FONT_SIZE)
pdf.add_text_wrap(cell_x(col), cell_y(row, 1), CELL_X, addr.address, FONT_SIZE)
pdf.add_text_wrap(cell_x(col), cell_y(row, 2), CELL_X, "#{addr.city}, #{addr.state} #{addr.zip}", FONT_SIZE)
end
end
pdf.select_font(FONT)
pages = @addresses.length / LABELS_PER_PAGE
pages += 1 if (@addresses.length % LABELS_PER_PAGE) > 0
0.upto(pages - 1) do |page|
start = page * LABELS_PER_PAGE
address_page = @addresses[start..start+LABELS_PER_PAGE]
0.upto(LABELS_PER_COL - 1) do |row|
add_label(row, 0, address_page[row*COLS], pdf)
add_label(row, 1, address_page[row*COLS+1], pdf)
add_label(row, 2, address_page[row*COLS+2], pdf)
end
pdf.new_page unless page + 1 == pages
end
And that’s it! Avery labels in Rails!
Posted in ruby, rails | Tags pdf, ruby, rubyonrails | no comments | no trackbacks
Posted by Nick Sieger
Fri, 05 May 2006 14:24:00 GMT
Spotted on ruby-talk today was this anecdote on a Ruby
hacker/father and son, and I just had to share here.
I trotted my 11 year old son over to the Poignant Guide and he
laughed like crazy at the Cartoon Foxes and did a little
programming, but soon got bored. Wait a minute Alex, let’s try one
more thing, Dwe.. Array. Wow, how do I make my R kill big time (He
knows all about cheats). I showed him the character’s values and he
promptly put in a hugh number for the Rabbit’s strength. He was
delighted to see the larger and larger negative life values appear
whenever he attacked. Dad, is this how all my Gameboy programs
work? Yes, son. Hey, dad I want to do 6dof animation too, can you
teach me? Yes son, here’s a few books for you -- Computer Graphics,
Foley et al and Physics for Game Developers, Bourg. Not sure he’ll
read them right away, but the whole episode saved me another $49.95
Game Cube cartridge.
Posted in ruby | no comments | no trackbacks
Posted by Nick Sieger
Tue, 02 May 2006 18:56:00 GMT
I had a chance to dabble around with Python a tiny bit today, building the XSV XML schema validator. Got it working fairly easily on my MacBook Pro after a minor detour. Later, I needed to build another copy on a shared linux dev box where I didn’t have root access. Now how does this work in Python? Fortunately, the answer was close at hand: a virtual python instance. Nice! You can create a replica of the main python install, and add your personal site-packages there. The only thing that gets copied is the python executable plus a bunch of symlinks to the main libraries and packages. After that point all you need to do is put your virtual python executable ahead of the main executable on your PATH.
If I were to install local packages/gems with Ruby, I’d probably either build my own Ruby or maintain a local packages directory and constantly customize RUBYLIB. Seems like a suboptimal solution. Has anyone attempted a virtual-ruby.rb that does the same as virtual-python.py?
Posted in ruby | 3 comments | no trackbacks
Posted by Nick Sieger
Sun, 23 Apr 2006 04:02:00 GMT
IRB (Interactive Ruby Shell) is one of those tools that a hacker
learning Ruby hopefully discovers right away. It’s an extremely
useful way to learn the language, verify hunches, test assumptions,
and get immediate feedback. IRB promotes learning by doing, which is
the best way of making something stick in your head. (You can even
try an online version of irb without even installing Ruby!)
The first order of business when using IRB is to setup your
preferences. If you haven’t done so already, create the file
~/.irbrc
(%USERPROFILE%.irbrc
on windows native ruby). .irbrc
is just a regular ruby script where you can run arbitrary ruby code at
the start of your IRB session. Add the following to .irbrc
:
require 'irb/completion'
ARGV.concat [ "--readline", "--prompt-mode", "simple" ]
This sets up usage of readline in your session and turns on TAB
completion, making IRB feel as comfortable as regular old bash
. Now
you can type Kernel::<TAB>
and get a list of available methods!
Good.
Next, the thing that you find yourself doing after using IRB for a
while is cutting and pasting code from your console buffer over to
your text editor. Don’t have Ruby’s reflection rules down yet? Not
sure whether to use instance_eval
or module_eval
when working on
that metaprogramming hack? Working inside Rails’ script/console
and
searching for the right ActiveRecord finder options? No matter how
good your terminal program, you probably have to use the mouse to
select text out of it to copy to your text editor, and hackers hate
having to switch from the keyboard to the mouse when in the flow of
programming.
So here’s a technique that will append commands entered in your IRB
session to a file in your home directory (idea from
ruby-talk:58931). Put the following in your .irbrc
:
module Readline
module History
LOG = "#{ENV['HOME']}/.irb-history"
def self.write_log(line)
File.open(LOG, 'ab') {|f| f << "#{line}
"}
end
def self.start_session_log
write_log("
# session start: #{Time.now}
")
at_exit { write_log("
# session stop: #{Time.now}
") }
end
end
alias :old_readline :readline
def readline(*args)
ln = old_readline(*args)
begin
History.write_log(ln)
rescue
end
ln
end
end
Readline::History.start_session_log
Now every line typed into IRB will immediately be saved into
~/.irb-history
. Exercise left to the reader to bind a custom
keystroke and macro to yank the last line out of that file and
automatically paste into your text editor.
Long-time bash
users know that the shell maintains a history of
commands across sessions so that you can access commands you typed
yesterday. Wouldn’t it be nice to do this in IRB as well? Wish
granted:
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
Happy ruby hacking! If you find any more handy IRB tips leave them at
rubygarden, and let me know about them.
Footnote: I realize there is duplication and non-DRY happening here
with two copies of your IRB history, but I came across these
techniques at two different times, and the functions they serve seem
different enough to potentially use them both. If you don’t like
that, choose whichever is more appropriate for your needs.
(Hope this post serves your needs Dan.)
Posted in ruby | 2 comments | no trackbacks