Posted on June 29, 2008 with 1 comment
I do a bit of freelance php work where I need to edit files through FTP. Textmate does not support this very well out of the box, and at first it seemed like I would have to open and edit each file in its own window. But by combining this tip by subtlegradient with this tip by ciaranwal.sh we can use tabbed editing, project drawer, and cmd+t to switch files. The steps:
1. In Cyberduck’s preferences make sure external editor is set to TextMate. Also, it helps if “Double click opens file in external editor” is set to true.
2. Open up a file from your FTP project that is close to the top level directory of your project, you’ll see why in a minute.
3. In the TextMate window that popped up, hit ctrl+shift+o (Bundles > Shell Script > Open Terminal). The terminal will open at the temporary location where the file you are editing is.
4. cd .. back to the top level directory of your project and enter: mate .
Now any subsequent files you open using Cyberduck will be added as tabs in the current TextMate project.
Posted on February 12, 2008 with 1 comment
The GoLark iPhone Application was released this week, making GoLark one step closer to providing us with local events, anywhere, at any time.
Currently, two of GoLark’s lists are supported on the iPhone: Top Larks and Top Recurring Larks. Date and time filtering–although slightly stripped down–is also provided. The app is purposely minimal in design, providing a clear and simple interface to the best local events.
Check it out at iphone.golark.com

Posted on November 17, 2007 with no comments
I haven’t posted in a while because GoLark is consuming all of my time, but tonight I felt compelled because of how cool this is. I needed to intermix two arrays, here is how I did it:
a1 = [1,2,3]
a2 = ["a","b","c"]
intermixed_array = [a1,a2].transpose.flatten
Yeah, no doubt. Is that obvious?
Posted on November 4, 2007 with no comments
I did a little experimenting with Processing, a language written for artists, graphics designers, and anyone interested in learning something new. I was very impressed with how easy it was to get started. The download comes with tons of simple example projects, and the API reference is easy to understand. I had hopes of Processing opening a whole, previously undiscovered, artistic side of my brain — it didn’t. But I did make a killer “blow up the falling spheres with my triangle’s laser” game. Check it out:

Wow, that screen shot makes it look even more lame than it really is (hard to do). Well, if you aren’t impressed with that, check out what someone with artistic talent can do with Processing.
I know, I know, you want the code so you can try this game out for yourself. Here it is, open with Processing and hit play.
Thanks for reading, now find something to do at GoLark.com
Posted on October 30, 2007 with 2 comments
A couple of weeks ago I hit multiple snags on my first attempt at installing memcached from source code on CentOS, hence the tutorial, “How to install memcached.” The fact that users found the tutorial by searching Google for the exact error messages in my post reassured me that I wasn’t just being an idiot. Here I will address a very similar problem and provide a once and for all solution.
I installed GNU’s Scientific Library and Ruby’s wrapper for GSL on Ubuntu and OS X without any problems. Next up: CentOS. The install appeared to complete successfully, but a require ‘gsl’ from irb showed otherwise:
LoadError: libgsl.so.0: cannot open shared object file: No such file or directory
I located libgsl.so.0 in /usr/local/lib; so once again I have a problem with the linker finding a shared library. The way I fixed this during the memcached install was to add the --rpath linker flag during the build. But I don’t wan’t to keep running into this in the future, so I decided to add /usr/local/lib to ld’s default search path, here’s how:
Open /etc/ld.so.conf and make sure there is a single line that reads:
include ld.so.conf.d/*.conf
Then, from bash prompt:
echo "/usr/local/lib" >> /etc/ld.so.conf.d/loc_lib.conf
/sbin/ldconfig
That should do it.
If you would like to learn more on the subject, this is the only good documentation I have found on Shared Library Search Paths.
Thanks for reading, now find something to do at GoLark.com
Posted on October 29, 2007 with no comments
Genius is a flash card program for Mac OS X that I came across on Lifehacker a few days ago. Using it is simple: you create a flash card set, Genius determines how often to display each card based on how well you have answered it in the past. The thing is, I don’t want to create the flashcard set, and you probably don’t either; that is the reason we never used flashcards in the first place. But I do want to expand my vocabulary, and Genius is certainly a tool that can help with that. So if you are also interested in a shiny new vocabulary, here’s what we can do: automate the flash card creation process.
The way we will do this is by creating a Ruby script that will parse Dictionary.com’s “Word of the Day” rss feed, then use AppleScript to add the word/definition pair to Genius. Finally, we will use crontab to automate the entire process. If all this sounds complicated, don’t worry, it is 90% copy-pasting.
Step 1: Create necessary directories
I am placing the Ruby and AppleScript files in ~/scripts, and the Genius flash card file in ~/flashcards, but feel free to use directories of your choice. From terminal:
mkdir ~/scripts
mkdir ~/flashcards
Step 2: Create empty .genius file
Open Genius and save a new (empty) file as ‘dictionary_wotd’ in the ~/flashcards directory. Close Genius.
Step3: Create a Ruby file to parse Dictionary.com’s word of the day rss feed
From terminal, create the file with:
touch ~/scripts/parse_wotd.rb; chmod 664 ~/scripts/parse_wotd.rb
Next, open ~/scripts/parse_wotd.rb in an editor and paste in this chunk of code:
require 'rubygems'
require 'hpricot'
require 'open-uri'
xml = Hpricot(open("http://dictionary.reference.com/wordoftheday/wotd.rss"))
desc = (xml/"item"/"description").inner_html
desc =~ /^([-\w]+):\s+(.+)/
word = $1
definition = $2.gsub(/^(\w)/) {|x| x.upcase}
system "osascript /Users/HOMEDIR/scripts/create_fcard.scpt " + word + " '" + definition + "'"
Be sure to replace HOMEDIR (line 12) with your own directory name (e.g. your username).
Save and quit. Also, make sure you have the Hpricot gem installed.
Step4: Create AppleScript file to add the word/definition pair to Genius
open Applications > AppleScript > Script Editor
then File > New
Paste in this chunk of code:
on run argv
tell application "Finder"
activate
open document file "dictionary_wotd.genius" of folder "flashcards" of folder "HOMEDIR" of folder "Users" of startup disk
end tell
tell application "Genius"
activate
end tell
tell application "System Events"
keystroke "N" using command down
keystroke item 1 of argv
keystroke "\t"
keystroke item 2 of argv
keystroke "s" using command down
delay .2
keystroke "w" using command down
end tell
end run
Again, be sure to replace HOMEDIR (line 4) with your own directory name. Save this file as ‘create_fcard’ in the ~/scripts directory. Close Script Editor.
We should test what we have so far, open terminal and:
cd ~/scripts
ruby parse_wotd.rb
Now open ~/flashcards/dictionary_wotd.genius and make sure the new card exists, if it does not, double check your paths in the .rb and .scpt files.
Finally, automate with crontab
From terminal:
crontab -e
This will open vi, add the following line to run the Ruby script every morning at 2:30 am:
30 2 * * * /PATH/TO/RUBY /Users/HOMEDIR/scripts/parse_wotd.rb
You can find your path to ruby by $which ruby. Also, I put a 30 second tutorial on vi at the end of this post for those that don’t know how to add the above line.
And that’s it! Every morning a new word will be added to your Dictionary.com flash card set — now it’s just a matter of actually studying them.
vi in 30 seconds:
to launch:
$vi FILENAME
x to delete
i to insert
esc to return to normal mode
:q! quits discarding changes
:wq quits saving changes
Thanks for reading, now find something to do at GoLark.com
Posted on October 19, 2007 with no comments
I have never been one to remember the number of days in a given month, and for a particular project I am working on I needed just that. I did a quick Google search to see if someone has already written a snippet of ruby code that will take care of this for me, and I found one here and here. The solution is as follows:
def DaysIn(MonthNum)
(Date.new(Time.now.year,12,31).to_date<<(12-MonthNum)).day
end
At first glance it seems like a fine solution — I’m getting 30s and 31s in all of the appropriate places — but then I do something that precludes this from being a reasonable solution: I benchmark it. Oh what a slippery slope it was, but I’ll get into that later. For those just looking for a ruby snippet for days in a month, I wrote an alternative solution that completes in about 2% of the time it takes the solution above:
def days_in_month(month, year)
feb = lambda do
if year % 400 == 0 || year % 4 == 0 && year % 100 != 0 then 29 else 28 end
end
day_array = [31, feb.call, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
day_array[month-1]
end
So what exactly caused the first solution to take so long? A quick benchmark exposes the culprit as Date.new. I have been doing a lot of date and time manipulations lately (naturalinputs.com is a natural language date and time parser), so I begin to worry. I decided to expand my investigation to Ruby’s Time Class, which I prefer to use over Date whenever possible; by passing appropriate strftime parameters I can accomplish most, if not all, of my needs with this class alone. In the past whenever I needed a particular date I would use Time.parse(”yyyymmdd”), which I always thought was working like a champ. Turns out it was working a lot less champ-like than I would have preferred. Two other flavors of Date creation that some of you may be using are Date.parse and Date.strptime. Then there is the DateTime class, with creation methods DateTime.civil, DateTime.parse, and DateTime.strptime. Every one of these methods is slow, horribly slow. But there is a better way, enter Time.local. Here is the benchmark (I created October 10, 2007 ten-thousand times in each case):
Date.strptime: 5.110000 0.370000 5.480000 ( 5.487217)
Date.parse: 5.920000 0.420000 6.340000 ( 6.329733)
Date.new: 1.010000 0.060000 1.070000 ( 1.068610)
DateTime.civil: 2.740000 0.240000 2.980000 ( 2.990096)
DateTime.parse: 8.310000 0.610000 8.920000 ( 8.916347)
DateTime.strptime: 7.350000 0.700000 8.050000 ( 8.046435)
Time.parse: 2.570000 0.110000 2.680000 ( 2.677252)
Time.local: 0.110000 0.010000 0.120000 ( 0.118345)
Yeah, crazy right? Yes, the parameter format of Time.local is annoying, but even using a wrapper to Time.local that takes the same parameters as Time.parse, such as:
class Time
class << self
# Instantiate a Time object with Time.quick_parse("YYYYMMDD")
def quick_parse(date_str)
local(date_str[0..3], RFC2822_MONTH_NAME[date_str[4..5].to_i - 1], date_str[6..7])
end
end
end
The benchmark comes out as:
Time.parse: 2.570000 0.110000 2.680000 ( 2.677252)
Time.local: 0.110000 0.010000 0.120000 ( 0.118345)
Time.quick_parse: 0.160000 0.010000 0.170000 ( 0.159252)
And now I can still use the “yyyymmdd” format that I have sprinkled throughout my app! Congratulations Time.local, you saved the day.
Posted on October 11, 2007 with 8 comments
I am using CentOS release 5; to find what version you are using, enter cat /etc/redhat-release
at a bash prompt. That is not to say that these steps won’t work for other linux distros, I just haven’t tried them. Anyway, when I first tried to install memcached I could not create the Makefile due to a dependence on libevent. So first, from /usr/local/src:
curl -O http://monkey.org/~provos/libevent-1.3e.tar.gz
tar xzvf libevent-1.3e.tar.gz
cd libevent-1.3e
./configure --prefix=/usr/local
make
make install
Hopefully everything went smoothly for you there. Now on to getting memcached, again from /usr/local/src:
curl -O http://www.danga.com/memcached/dist/memcached-1.2.2.tar.gz
tar xzvf memcached-1.2.2.tar.gz
cd memcached-1.2.2
LDFLAGS='-Wl,--rpath /usr/local/lib' ./configure --prefix=/usr/local
make
make install
Now:
memcached -d -u root
No errors, let’s make sure it’s running:
ps aux | grep memcached
Awesome! Hey, that’s the name of the blog, how unoriginal.
Now to stop it:
pkill memcached
I hope that saved you some time.
For those curious as to what that LDFLAGS='-Wl,--rpath /usr/local/lib' is all about, enter at a bash prompt man ld
This post prevents the following errors:
configure: error: libevent is required
If It’s already installed, specify its path using –with-libevent=/dir/
memcached: error while loading shared libraries: libevent-1.3e.so.1: cannot open shared object file: No such file or directory
Thanks for reading, now find something to do at GoLark.com
Posted on October 5, 2007 with no comments
Within a form, an auxiliary submit button associated with a single text field is often useful. Here’s how to make the ‘enter’ key submit the auxiliary button, as opposed to the entire form.
<form method="post" onsubmit="alert('submitting form')">
<input type="text" onkeypress="return js_on_enter(event, function(){document.getElementById('aux').click()})">
<input id="aux" type="button" value="aux submit" onclick="alert('aux');"><br>
<input type="text"><br>
<input type="submit" value="form submit">
</form>
Now for the javascript:
<script type="text/javascript">
function js_on_enter(e, func) // Takes event instance and js function as params
{
if (!e) e = window.event; // IE appends event instance to window object
if (e.keyCode == '13')
{
func();
return false;
}
return true;
}
</script>
Thanks for reading, now find something to do at GoLark.com
Posted on September 27, 2007 with 1 comment
In this case it is best to learn by example, fire up irb and enter:
str = "this string has ruby in it"
re = 'ruby'
str =~ /#{re}/
The 16 that gets returned is the location of the first matching character, ‘r’. You can also use this with gsub, for instance:
str = "uhhhh, I don't have a good example"
speech_correcting_reg_ex = 'uh+,?\s?'
str.gsub!(/#{speech_correcting_reg_ex}/,'')
And just like that, we have proper English. Should there be a comma there?
Thanks for reading, now find something to do at GoLark.com