Ruby
Fixing UUID generation on DreamHost
Submitted by Duncan Bayne on Tue, 2009-11-10 05:37Dreamhost recently changed their configuration (at least on our server) to prevent users from running ifconfig. This causes UUID generation to fail, with an error like this showing up in the Rails log:
An exception was thrown while generating the temp path. all of /sbin/ifconfig /bin/ifconfig ifconfig ipconfig /all failed.
Long story, short form: the uuid Gem relies upon the macaddr Gem, which in turn uses one of the above binaries to determine the MAC address of the machine it's running on. So if you can't execute ifconfig (or ipconfig if you're on Windows) then UUID.generate will fail.
There are two possible fixes. Either you can change your code to use the uuidtools Gem, which seems to work nicely without being able to run ifconfig. Or, you can tell the macaddr Gem what the MAC address is in your environment.rb file:
require 'uuid' # Specify a MAC address because Dreamhost doesn't allow us to run ifconfig. Mac.mac_address = '00:1f:e0:8c:0f:23'
Either works - I think the former is a better way of doing it (or you'll be modifying your environment.rb file for every machine to which you deploy) but the latter is certainly faster if you're in a hurry.
My first real-world LISP code
Submitted by Duncan Bayne on Thu, 2009-09-10 00:56I have deleted The GitHub repositories referred to in this post; see Clearing the deck for details.
I sometimes find myself with the need to close all unmodified buffers in Emacs that pertain to files (not all buffers do pertain to files; e.g. some contain terminal sessions).
I could have done this with M-x kill-some-buffers but this prompts for each buffer; what I wanted was something that would just silently kill any file buffer that didn't have unsaved changes.
So I wrote the following, and added it to my duncans_emacs repo on GitHub.
(defun duncans_emacs:kill-unmodified-buffers()
"Kill any unmodifier buffers that are inspecting files."
(interactive)
(mapcar
'(lambda (buf)
(if (and (buffer-file-name buf) (not (buffer-modified-p buf)))
(kill-buffer buf)))
(buffer-list)))
(provide 'kill-unmodified-buffers)For those unfamiliar with Elisp (the LISP dialect that Emacs is mostly written in):
mapcartakes a lambda function and a list, then runs the lambda function against each element of the list in turn.interactivelets Emacs know that this function can be called by the user usingM-x.buffer-file-namereturns nil if the buffer in question doesn't pertain to a file (for example, a buffer that contains a terminal).- Elisp doesn't have namespaces, so the function name is prefixed with the package name (duncans_emacs) to avoid collisions.
After finishing this, it dawned on me that LISP isn't what I'd call intuitive or easy to read (although this might improve with time as I'm still a rank LISP beginner). An equivalent script for an (hypothetical) Ruby-based editor might look something like this:
# Kill any unmodifier buffers that are inspecting files.
def kill-unmodified-buffers
buffer_list.each { |buf|
buf.kill() if (buf.file? && !buf.modified?)
}
end(This is assuming that there's a method by which the parent class can identify user-callable functions). Now I'll concede that LISP has many positive attributes. Terseness and similarity to written English are not two of those, however :-)
Helping out over at RailsForum
Submitted by Duncan Bayne on Sat, 2009-06-13 23:53Every day I'm at work, I'm going to try to answer one unanswered thread over at RailsForum. The idea is to keep my skills sharp across all areas of RoR, to help to keep the Rails as helpful and friendly as it's currently known for being, and of course to boost my own & my company's profile on the 'net.
Andelys - the power user's media player
Submitted by Duncan Bayne on Tue, 2008-11-18 07:36
Project information is here and I've also put up a screencast; together these should give you an idea of what I'm trying to build. Bear in mind it's very early days yet; what you see here is pretty much all it can currently do.
HOWTO: Debugging Rails tests with rdebug
Submitted by Duncan Bayne on Sun, 2008-07-27 08:37Let's take a contrived & hypothetical example that's easy to follow. I have a method which is supposed to add two numbers and return the result, or 10, whichever is higher. But when I run it ...
duncan@duncan-desktop:~/demo$ rake test:units
(in /home/duncan/demo)
/usr/bin/ruby1.8 -Ilib:test "/usr/lib/ruby/1.8/rake/rake_test_loader.rb" "test/unit/calculator_test.rb"
Loaded suite /usr/lib/ruby/1.8/rake/rake_test_loader
Started
F
Finished in 0.027942 seconds.
1) Failure:
test_add_to_max_of_ten_limits_to_ten(CalculatorTest)
[./test/unit/calculator_test.rb:6:in `test_add_to_max_of_ten_limits_to_ten'
/home/duncan/demo/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/testing/default.rb:7:in `run']:
<10> expected but was
<11>.
1 tests, 1 assertions, 1 failures, 0 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby1.8 -Ilib:test "/usr/lib/ruby...]
(See full trace by running task with --trace)
The first thing I need to do is install the ruby-debug gem:
duncan@duncan-desktop:~/demo$ sudo gem install ruby-debug
Successfully installed ruby-debug-0.10.1
Installing ri documentation for ruby-debug-0.10.1...
Installing RDoc documentation for ruby-debug-0.10.1...
... and then test that it's been installed:
duncan@duncan-desktop:~/demo$ rdebug --version
ruby-debug 0.10.1
If you see an error like rdebug: command not found then you'll need to add your gem bin directory to your PATH. On Xubuntu I added the following line to ~/.bashrc:
export PATH=$PATH:/var/lib/gems/1.8/bin
Back to the code; now I can add a breakpoint to the calculator model. To add an rdebug breakpoint all I need to do is call debugger; in this case I'll make it conditional upon the two parameters totalling to more than 10:
class Calculator < ActiveRecord::Base
def self.add_to_a_max_of_ten(a, b)
result = 0
debugger if a + b > 10
if result > 10
result = 10
end
result = a + b
return result
end
end
Then I run the test through rdebug:
duncan@duncan-desktop:~/demo$ rdebug test/unit/calculator_test.rb
test/unit/calculator_test.rb:1
require File.dirname(__FILE__) + '/../test_helper'
(rdb:1)
The debugger breaks automatically at the start of the test; I can make it continue easily enough:
(rdb:1) continue
Loaded suite test/unit/calculator_test
Started
/home/duncan/demo/app/models/calculator.rb:6
if result > 10
Right, now I'm at the point where I can start examining the program flow and figuring out why it's failing. Firstly, what's the value of result at this point?
(rdb:1) var local
a => 5
b => 6
result => 0
Ohhhh, right. That might be the problem. So, where am I again in the source? I can take a look at the source with the list command:
(rdb:1) list =
[1, 10] in /home/duncan/demo/app/models/calculator.rb
1 class Calculator < ActiveRecord::Base
2
3 def self.add_to_a_max_of_ten(a, b)
4 result = 0
5 debugger if a + b > 10
=> 6 if result > 10
7 result = 10
8 end
9 result = a + b
10 return result
At this point, I can see what's going to happen - the interpreter will skip to line 9, perform the addition, and return whatever the result is. But being the cynical soul that I am (when it comes to anything electronic) I can verify this by stepping over the next few lines, and verify the result before it's returned:
(rdb:1) next
/home/duncan/demo/app/models/calculator.rb:9
result = a + b
(rdb:1) next
/home/duncan/demo/app/models/calculator.rb:10
return result
(rdb:1) var local
a => 5
b => 6
result => 11
So now, I can go on to fix the method, and verify the fix by observing that the test passes.
Playing around with Ruby metaprogramming
Submitted by Duncan Bayne on Mon, 2008-03-24 14:26Recently I've started using Ruby for general-purpose scripting and small apps on Linux, and I'm enjoying it a lot. However I've been parsing command line arguments in the 'old way' that hasn't changed much since the days of C. It works, but it's not particularly elegant. Back when I switched to .NET from C, I wrote NArg as a .NET-esque implementation of command-line argument parsing ... surely it couldn't be that hard to do the same for Ruby?
The short answer is that I've been playing with metaprogramming in Ruby for a while now and no, it doesn't look like it'll be too hard (thanks in no small part to some excellent tips from Ola Bini). If, like me, you're used to non-dynamic languages it might take a few seconds for the beauty of this to sink in ...
module Kernel
def singleton_class
class << self; self; end
end
end
module Args
def has_argument(name, default)
singleton_class.send(:define_method, "cli_#{name}") do
default
end
end
end
class App
extend Args
has_argument 'somearg', 'default'
print "#{cli_somearg}\n"
end
Sure enough, when you run it, you get the following written to console ...
default
This is the conceptual basis I'll be using to build my CLI parsing module - dynamically building CLI parsing code into classes that need it by using mixins and metaprogramming. And yes, I'm 100% certain that such a thing must already exist ... but the point here is to become completely familiar with Ruby metaprogramming, even if I will have reinvented the wheel in the process



Recent comments
1 week 1 day ago
3 weeks 3 days ago
3 weeks 6 days ago
11 weeks 1 day ago
15 weeks 5 days ago
31 weeks 18 hours ago
31 weeks 23 hours ago
37 weeks 3 days ago
37 weeks 3 days ago
37 weeks 4 days ago