Archive for the ‘Programming’ Category
August 27th, 2010
If you upgrade SMF from 1.1.2 all the way to 1.1.11 there is a missing chunk of SQL upgrade. The `smf_board_permissions` table has `permission` VARCHAR(10) but there are permissions like "post_reply_new" which gets silently shaved into "post_reply" due to the column length limitation leaving you tearing your hair out. (Well it did me. I was editing templates and everything.) This results in situations where forum users can no longer reply to posts and trying to edit forum permissions results in database error messages due to duplicate keys ("post_reply_own" and "post_reply_any" both get shaved into "post_reply" for example).
Alter the column `permission` to VARCHAR(50) and it'll work again.
October 22nd, 2009
I attended Andy Hunt's “Refactor Your Wetware: Pragmatic Thinking and Learning” presentation given for the Richmond Java User Group/Central VA Ruby User Group October meeting Wednesday night. Having just completed this book in September I was very interested in reinforcing what I have learned (and began practicing, ahem, mind mapping) and excited to see the author present this material.
I was impressed with the professional atmosphere and organization at this event.
Andy’s presentation centered around the book, touching on several highlights over the two hour period. This was largely a rehash for me, which was very good, with a little bit of new material thrown in. (There is a new Pomodoro book pragprog is publishing so there was a brief overview of Pomodoro included with a plug – which I fully support at free/sponsored events; I had just read the RSS post earlier in the day so I would have been disappointed if it were skipped!) His slides were good – not distracting – and the presentation was delivered with animation and some really well placed humor.
Points [I remember]:
Dreyfus Model of Skill Acquisition
Mind mapping (easily my favorite technique I learned from the book)
You cannot execute a great idea if you don’t exercise your brain to get it to produce them – write down your ideas, all of them
Meditation
How context switching and multitasking damages productivity
Have a personal wiki
Book study groups – going to suggest replacing our low value formal code reviews with this in an on-going basis
Finally Andy said it may be possible in the near future to get some of pragprog’s non-code books in an audio book format which for anyone who has a long commute is very good news.
October 22nd, 2009
My solution was selected as the winning solution for RubyLearning.com’s RPCFN #2 “Average Arrival Time for A Flight.”
This challenge involved averaging times of the day without the actual day in the context. When I first started to tackle the problem I thought to myself that this will be very easy. Then I hit the “no day” context and realized that this problem was much tougher than I anticipated. When I finally saw the posted solutions including Chris Strom’s (blog) it was like decades old high school math came rushing back to me. I would have never thought of plotting points on a graph but now that I’ve been exposed I’m certain I will never forget it!
My friend [and commuting body] Matt and I talked through the problem during our drive home as we sat in Virginia I-495 outer loop and I-95S traffic. He had some ideas about plotting the problem linearly around 0 but ultimately I ended up going with making assumptions about how close the provided times were to midday and midnight.
require 'time'
SECONDS_IN_DAY = 86400
MIDNIGHT = Time.parse("12:00AM").to_i
MIDDAY = Time.parse("12:00PM").to_i
def average_time_of_day(times)
seconds = []
times.each {|time| seconds << Time.parse(time).to_i}
seconds.sort!
if (seconds.first - MIDNIGHT) < (seconds.last - MIDDAY)
seconds.map! {|s| s < MIDDAY ? s += SECONDS_IN_DAY : s }
end
Time.at(seconds.inject { |sum,n| sum += n }.to_f / seconds.length).strftime("%I:%M%p").downcase
end
Gist: https://gist.github.com/5b371226faf83af50d7e
Interview: http://rubylearning.com/blog/2009/10/22/charles-feduke-winner-rpcfn-2/
September 29th, 2009
Working on the RPCFN: Shift Subtitle I found myself having to work with files input as a stream (or anyway that’s how I wanted to approach the problem; streams are efficient to me). In order to give my code any sort of unit testing justice I needed to mock the file system. The challenge expressly forbids any Ruby gems from being used in the script itself – and maybe by extension the unit tests as well – but I could not see devoting the time necessary to write a mocking framework for the file system.
I found a gem that does precisely what I needed named Construct. Unfortunately there is a bug with Ruby 1.8.6 on Windows in regards to clean up of temp files. The problem is that when attempting to clean up a Errno::EACCES is raised causing the unit test to fail (or you to write a lot of rescue blocks).
A workaround I came up with was to replace the rmtree method in the Pathname class within my unit test to perform no clean up. Not the best approach I am sure, but it let me get on with my work.
# something_test.rb
require "test/unit"
require 'construct'
require 'something'
class Pathname
# windows has problems with temp files created by Ruby
# http://redmine.ruby-lang.org/issues/show/1494
def rmtree
nil
end
end
class SomethingTest < Test::Unit::TestCase
# test methods...
end
September 26th, 2009
I’m working on the RubyLearning blog’s Ruby Programming Challenge for Newbies #1 to learn the language – I’ve done a bit with Rails and some admin scripts so I could use the exposure. Since I love TDD approaching Ruby development through RSpec is only natural, but it was a pain in the ass trying to find how I could have RSpec verify that my program properly exited when certain conditions were met. Here’s how I solved it, reposted here:
# something.rb
class Something
def initialize(kernel=Kernel)
@kernel = kernel
end
def process_arguments(args)
@kernel.exit
end
end
# something_spec.rb
require 'something'
describe Something do
before :each do
@mock_kernel = mock(Kernel)
@mock_kernel.stub!(:exit)
end
it "should exit cleanly" do
s = Something.new(@mock_kernel)
@mock_kernel.should_receive(:exit)
s.process_arguments(["-h"])
end
end
What I learned was that you can define a constructor with optional arguments (in this case, initialize(kernel=Kernel) and then proceed to use @kernel’s methods instead of the methods that Kernel provides when you do not specify a class instance. With a properly mocked and stubbed exit method in my spec things operate as expected.