diff --git a/files/mephisto_converters-typo-schema_version_61.patch b/files/mephisto_converters-typo-schema_version_61.patch new file mode 100644 index 0000000..50aa741 --- /dev/null +++ b/files/mephisto_converters-typo-schema_version_61.patch @@ -0,0 +1,81 @@ +diff -Nupr mephisto_converters/lib/converters/typo/article.rb mephisto_converters-schema_61/lib/converters/typo/article.rb +--- mephisto_converters/lib/converters/typo/article.rb 2006-11-23 10:57:06.000000000 -0800 ++++ mephisto_converters-schema_61/lib/converters/typo/article.rb 2007-05-26 01:54:19.000000000 -0700 +@@ -1,7 +1,8 @@ + module Typo + class Article < Content +- has_many :comments, :dependent => true, :order => "created_at ASC", :class_name => 'Typo::Comment' ++ has_many :comments, :dependent => :destroy, :order => "created_at ASC", :class_name => 'Typo::Comment' + has_and_belongs_to_many :tags, :class_name => 'Typo::Tag' +- has_and_belongs_to_many :categories, :class_name => 'Typo::Category' ++ has_many :categorizations, :class_name => 'Typo::Categorization' ++ has_many :categories, :class_name => 'Typo::Category', :through => :categorizations + end + end +diff -Nupr mephisto_converters/lib/converters/typo/categorization.rb mephisto_converters-schema_61/lib/converters/typo/categorization.rb +--- mephisto_converters/lib/converters/typo/categorization.rb 1969-12-31 16:00:00.000000000 -0800 ++++ mephisto_converters-schema_61/lib/converters/typo/categorization.rb 2007-05-26 01:44:19.000000000 -0700 +@@ -0,0 +1,7 @@ ++module Typo ++ class Categorization < ActiveRecord::Base ++ establish_connection configurations['typo'] ++ belongs_to :article, :class_name => 'Typo::Article' ++ belongs_to :category, :class_name => 'Typo::Category' ++ end ++end +diff -Nupr mephisto_converters/lib/converters/typo/category.rb mephisto_converters-schema_61/lib/converters/typo/category.rb +--- mephisto_converters/lib/converters/typo/category.rb 2006-11-23 10:57:06.000000000 -0800 ++++ mephisto_converters-schema_61/lib/converters/typo/category.rb 2007-05-26 01:42:02.000000000 -0700 +@@ -1,6 +1,7 @@ + module Typo + class Category < ActiveRecord::Base + establish_connection configurations['typo'] +- has_and_belongs_to_many :articles, :class_name => 'Typo::Article' ++ has_many :categorizations, :class_name => 'Typo::Categorization' ++ has_many :articles, :class_name => 'Typo::Article', :through => :categorizations + end + end +diff -Nupr mephisto_converters/lib/converters/typo/comment.rb mephisto_converters-schema_61/lib/converters/typo/comment.rb +--- mephisto_converters/lib/converters/typo/comment.rb 2006-11-23 10:57:06.000000000 -0800 ++++ mephisto_converters-schema_61/lib/converters/typo/comment.rb 2007-05-26 01:54:30.000000000 -0700 +@@ -1,5 +1,7 @@ + module Typo +- class Comment < Content +-# belongs_to :article, :foreign_key => 'parentid', :class_name => 'Typo::Comment' ++ class Comment < Feedback ++ establish_connection configurations['typo'] ++ belongs_to :article, :class_name => 'Typo::Article' ++ belongs_to :user, :class_name => 'Typo::User' + end + end +diff -Nupr mephisto_converters/lib/converters/typo/feedback.rb mephisto_converters-schema_61/lib/converters/typo/feedback.rb +--- mephisto_converters/lib/converters/typo/feedback.rb 1969-12-31 16:00:00.000000000 -0800 ++++ mephisto_converters-schema_61/lib/converters/typo/feedback.rb 2007-05-26 01:55:28.000000000 -0700 +@@ -0,0 +1,6 @@ ++module Typo ++ class Feedback < Content ++ set_table_name 'feedback' ++ establish_connection configurations['typo'] ++ end ++end +diff -Nupr mephisto_converters/lib/converters/typo.rb mephisto_converters-schema_61/lib/converters/typo.rb +--- mephisto_converters/lib/converters/typo.rb 2006-11-23 10:57:06.000000000 -0800 ++++ mephisto_converters-schema_61/lib/converters/typo.rb 2007-05-26 01:53:14.000000000 -0700 +@@ -1,8 +1,10 @@ + require 'converters/typo/content' + require 'converters/typo/page' + require 'converters/typo/article' ++require 'converters/typo/feedback' + require 'converters/typo/comment' + require 'converters/typo/category' ++require 'converters/typo/categorization' + require 'converters/typo/user' + require 'converters/typo/tag' + +@@ -77,4 +79,4 @@ class TypoConverter < BaseConverter + memo << (sections[::Section.permalink_for(cat.name)] || site.sections.create(:name => cat.name)).id + end + end +-end +\ No newline at end of file ++end diff --git a/images/ch1-Z-G-4.gif b/images/ch1-Z-G-4.gif new file mode 100644 index 0000000..c8bada3 Binary files /dev/null and b/images/ch1-Z-G-4.gif differ diff --git a/published/2006.02.23-sjs-rails-bundle-0.2-for-textmate.md b/published/2006.02.23-sjs-rails-bundle-0.2-for-textmate.md new file mode 100644 index 0000000..79145d6 --- /dev/null +++ b/published/2006.02.23-sjs-rails-bundle-0.2-for-textmate.md @@ -0,0 +1,31 @@ +Title: SJ's Rails Bundle 0.2 for TextMate +Date: February 23, 2006 +Timestamp: 1140743880 +Author: sjs +Tags: textmate, rails, coding, bundle, macros, rails, snippets, textmate +Styles: typocode +---- + +Everything that you've seen posted on my blog is now available in one bundle. Snippets for Rails database migrations and assertions are all included in this bundle. + +There are 2 macros for class-end and def-end blocks, bound to ⌃C and ⌃D respectively. Type the class or method definition, except for class or def, and then type the keyboard shortcut and the rest is filled in for you. + +I use an underscore to denote the position of the cursor in the following example: + + +
method(arg1, arg2_)
+ +Typing ⌃D at this point results in this code: + + +
def method(arg1, arg2)
+  _
+end
+ +There is a list of the snippets in Features.rtf, which is included in the disk image. Of course you can also browse them in the Snippets Editor built into TextMate. + +Without further ado, here is the bundle: + +

Download Download SJ's Rails Bundle 0.2

+ +This is a work in progress, so any feedback you have is very helpful in making the next release better. diff --git a/published/2006.03.03-i-dont-mind-fairplay-either.md b/published/2006.03.03-i-dont-mind-fairplay-either.md new file mode 100644 index 0000000..9b6070c --- /dev/null +++ b/published/2006.03.03-i-dont-mind-fairplay-either.md @@ -0,0 +1,22 @@ +Title: I don't mind FairPlay either +Date: March 3, 2006 +Timestamp: 1141451760 +Author: sjs +Tags: apple, mac os x, life, drm, fairplay, ipod, itunes +---- + +I think that Jim is right about Apple's DRM not being all that evil. + +I buy music from the iTunes Music Store *because* I bought an iPod. The fact I can't play them on another device doesn't matter to me. With my purchased songs I can: + + * listen to the songs I buy all I want + * burn them to CD + * stream them to my amplifier via AirPort Express + +I don't buy a ton of music from the iTMS, but I can't tell the difference between any of those songs and the songs I ripped from CDs and they're all mixed in one collection. That's good enough for me. + +I dislike DRM as much as the next guy, but like CSS encryption on DVDs, FairPlay is something I can live with. + +It reminds me of how here in North America I have to live with the crappy cell phone companies that lock their phones to their networks. If it's something I need or want, sometimes I'll live with restrictions because there are no alternatives yet. + +*__Update:__ It's almost settled. The pope got an iPod so all that's left is to see if he buys any music off of iTunes. If he does, then it can't be evil. heh...* diff --git a/published/2006.03.03-spore.md b/published/2006.03.03-spore.md new file mode 100644 index 0000000..11deefb --- /dev/null +++ b/published/2006.03.03-spore.md @@ -0,0 +1,10 @@ +Title: Spore +Date: March 3, 2006 +Timestamp: 1141450980 +Author: sjs +Tags: amusement, technology, cool, fun, games +---- + +This game that Jim blogged about is probably the coolest game I've seen. + +You really just have to watch the video, I won't bother explaining it here. I don't really play games much, but this I would play. diff --git a/published/2006.05.07-os-x-and-fitts-law.md b/published/2006.05.07-os-x-and-fitts-law.md new file mode 100644 index 0000000..6f943e1 --- /dev/null +++ b/published/2006.05.07-os-x-and-fitts-law.md @@ -0,0 +1,8 @@ +Title: OS X and Fitt's law +Date: May 7, 2006 +Timestamp: 1147059780 +Author: sjs +Tags: mac os x, apple, mac, os, usability, x +---- + +I've realized that OS X really does obey Fitt's law in all 4 corners now. Apple menu in the top left, Spotlight top right, and the bottom 2 are always accessible for drag n drop, unless the dock is hidden. I rarely ever use it because I usually have pretty good chunks of the desktop showing, but it is useful. diff --git a/published/2006.05.07-wikipediafs-on-linux-in-python.md b/published/2006.05.07-wikipediafs-on-linux-in-python.md new file mode 100644 index 0000000..485f739 --- /dev/null +++ b/published/2006.05.07-wikipediafs-on-linux-in-python.md @@ -0,0 +1,10 @@ +Title: WikipediaFS on Linux, in Python +Date: May 7, 2006 +Timestamp: 1147060140 +Author: sjs +Tags: hacking, python, linux, fuse, linux, mediawiki, python, wikipediafs +---- + +Till now I've been using my own version of pywikipedia for scripting MediaWiki, and it works well. But I read about WikipediaFS and had to check it out. It's a user space filesystem for Linux that's built using the Python bindings for FUSE. What it does is mounts a filesystem that represents your wiki, with articles as text files. You can use them just like any other files with mv, cp, ls, vim, and so on. + +There hasen't been any action on that project for 13 months though, and it doesn't work on my wiki (MediaWiki 1.4.15) so I'm going to try and make it work after I upgrade to MediaWiki 1.6.3 tonight. This will be pretty cool when it works. I haven't looked at the code yet but it's only 650 lines. diff --git a/published/2006.06.11-apple-pays-attention-to-detail.md b/published/2006.06.11-apple-pays-attention-to-detail.md new file mode 100644 index 0000000..5805727 --- /dev/null +++ b/published/2006.06.11-apple-pays-attention-to-detail.md @@ -0,0 +1,8 @@ +Title: Apple pays attention to detail +Date: June 11, 2006 +Timestamp: 1150014600 +Author: sjs +Tags: technology, mac os x, apple +---- + +I think this has to be one of the big reasons why people who love their Mac, love their Mac (or other Apple product). I usually just have cheap PC speakers plugged into my Mac mini, but I didn't bring any with me to Munich and the internal Mac mini speaker isn't very loud, so I'm using headphones to watch movies. My Mac remembers the volume setting when the headphones ore plugged in, and when they're not, so I don't accidentally blow my ears. It's like my iPod pausing when the headphones are unplugged. It's excruciating attention to the smallest, (seemingly) most unimportant detail. I love it, and I'm hooked. diff --git a/published/2006.07.17-ruby-and-rails-have-spoiled-me-rotten.md b/published/2006.07.17-ruby-and-rails-have-spoiled-me-rotten.md new file mode 100644 index 0000000..21fed1f --- /dev/null +++ b/published/2006.07.17-ruby-and-rails-have-spoiled-me-rotten.md @@ -0,0 +1,16 @@ +Title: Ruby and Rails have spoiled me rotten +Date: July 17, 2006 +Timestamp: 1153140000 +Author: sjs +Tags: rails, ruby, php, coding, framework, php, rails, ruby, zend +---- + +It's true. I'm sitting here coding in PHP using the Zend Framework and all I can think about is how much nicer Rails is, or how much easier it is to do [x] in Ruby. It's not that the Zend Framework is bad or anything, it's quite nice, but you just can't match Ruby's expressiveness in a language like PHP. Add the amazing convenience Rails builds on top of Ruby and that's a really hard combo to compete with. + +I'd love to be using mixins instead of mucking around with abstract classes and interfaces, neither of which will just let you share a method between different classes. Writing proxy methods in these tiny in-between classes is annoying. (ie. inherit from Zend_class, then my real classes inherit from the middle-man class) I *could* add things to Zend's classes, but then upgrades are a bitch. I miss Ruby. I could use something like whytheluckystiff's PHP mixins, which is a clever hack, but still a hack. + +I keep looking at Rails code to see how things are done there, and I already coded a nearly complete prototype in Rails as a reference. I could have finished the thing in Rails by now, seriously. I'm still playing catch-up writing validations and model classes for all my objects, stuff I could've had for free using Rails, with an extra 10 mins to add validations and make sure they're all working nicely. + +It's no wonder David H. Hansson wasn't able to write a framework he was happy with in PHP. After using Rails everything seems like a chore. I'm just coding solved problems over again in an inferior language. + +But hey, I'm learning things and I still got to use Ruby even if the code won't be used later. I guess this experience will just make me appreciate the richness of Ruby and Rails even more. diff --git a/published/2006.07.19-late-static-binding.md b/published/2006.07.19-late-static-binding.md new file mode 100644 index 0000000..b192ee1 --- /dev/null +++ b/published/2006.07.19-late-static-binding.md @@ -0,0 +1,47 @@ +Title: Late static binding +Date: July 19, 2006 +Timestamp: 1153329780 +Author: sjs +Tags: php, coding, coding, php +---- + +*Update: This has been discussed and will be uh, sort of fixed, in PHP6. You'll be able to use static::my_method() to get the real reference to self in class methods. Not optimal, but still a solution I guess.* + +As colder on ##php (freenode) told me today, class methods in PHP don't have what they call late static binding. What's that? It means that this code: + +
+
+class Foo
+{
+  public static function my_method()
+  {
+    echo "I'm a " . get_class() . "!\n";
+  }
+}
+
+class Bar extends Foo
+{}
+
+Bar::my_method();
+
+
+ +outputs "I'm a Foo!", instead of "I'm a Bar!". That's not fun. + +Using __CLASS__ in place of get_class() makes zero difference. You end up with proxy methods in each subclass of Foo that pass in the real name of the calling class, which sucks. + +
+
+class Bar extends Foo
+{
+  public static function my_method()
+  {
+    return parent::my_method( get_class() );
+  }
+}
+
+
+ +I was told that they had a discussion about this on the internal PHP list, so at least they're thinking about this stuff. Too bad PHP5 doesn't have it. I guess I should just be glad I won't be maintaining this code. + +The resident PHP coder said "just make your code simpler", which is what I was trying to do by removing duplication. Too bad that plan sort of backfired. I guess odd things like this are where PHP starts to show that OO was tacked on as an after-thought. diff --git a/published/2006.07.21-class-method-instance-method-it-doesnt-matter-to-php.md b/published/2006.07.21-class-method-instance-method-it-doesnt-matter-to-php.md new file mode 100644 index 0000000..210ded7 --- /dev/null +++ b/published/2006.07.21-class-method-instance-method-it-doesnt-matter-to-php.md @@ -0,0 +1,56 @@ +Title: Class method? Instance method? It doesn't matter to PHP +Date: July 21, 2006 +Timestamp: 1153493760 +Author: sjs +Tags: php, coding +---- + +*Update: This has been discussed for PHP6. A little late, but I guess better than never.* + +I made a mistake while I was coding, for shame! Anyway this particular mistake was that I invoked a class method on the wrong class. The funny part was that this method was an instance method in the class which I typed by mistake. In the error log I saw something like "Invalid use of $this in class function." + +I knew for a fact I hadn't used $this in a class method, so it was kind of a confusing error. I went to the file in question and found out that it was calling an instance method as a class method. Now that is some crazy shit. + +I would fully expect the PHP parser to give me an error like "No class method [foo] in class [blah]", rather than try and execute it as a class method. The syntax is completely different; you use :: to call a class method and -> to call an instance method. And you use the name of a class when you call a class method. + +This code: + +

+class Foo {
+  public static function static_fun()
+  {
+    return "This is a class method!\n";
+  }
+
+  public function not_static()
+  {
+    return "This is an instance method!\n";
+  }
+}
+
+echo '<pre>';
+echo "From Foo:\n";
+echo Foo::static_fun();
+echo Foo::not_static();
+echo "\n";
+
+echo "From \$foo = new Foo():\n";
+$foo = new Foo();
+echo $foo->static_fun();
+echo $foo->not_static();
+echo '</pre>';
+
+ +Produces: + +

+From Foo:
+This is a class method!
+This is an instance method!
+
+From $foo = new Foo():
+This is a class method!
+This is an instance method!
+
+ +What the fuck?! http://www.php.net/manual/en/language.oop5.static.php is lying to everyone. diff --git a/published/2006.08.22-where-are-my-headphones.md b/published/2006.08.22-where-are-my-headphones.md new file mode 100644 index 0000000..90fb878 --- /dev/null +++ b/published/2006.08.22-where-are-my-headphones.md @@ -0,0 +1,8 @@ +Title: Where are my headphones? +Date: August 22, 2006 +Timestamp: 1156257060 +Author: sjs +Tags: life, seekport +---- + +Some people left Seekport this month and 2 of the remaining employees moved into the office I’m working in. That’s fine, and I’m leaving at the end of the week, but man I’m going crazy. This guy’s pounding on his keyboard like it’s a fucking whack-a-mole game! I don’t know what kind of keyboard he learned to type on but it must’ve been horrible. It sounds like he must go through at least 10 of those things in a year. I don’t know if I’ll make it till Friday without yelling "AGH! STOP THE MADNESS YOU CRAZY BASTARD YOU JUST HAVE TO TOUCH THE KEYS!" diff --git a/published/2006.09.16-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo.md b/published/2006.09.16-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo.md new file mode 100644 index 0000000..7450836 --- /dev/null +++ b/published/2006.09.16-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo-buffalo.md @@ -0,0 +1,10 @@ +Title: Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo +Date: September 16, 2006 +Timestamp: 1158469860 +Author: sjs +Tags: amusement, buffalo +---- + +Wouldn't the sentence 'I want to put a hyphen between the words Fish and And and And and Chips in my Fish-And-Chips sign' have been clearer if quotation marks had been placed before Fish, and between Fish and and, and and and And, and And and and, and and and And, and And and and, and and and Chips, as well as after Chips? + +→ Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo diff --git a/published/2007.04.04-a-triple-booting-schizophrenic-macbook.md b/published/2007.04.04-a-triple-booting-schizophrenic-macbook.md new file mode 100644 index 0000000..4d803e9 --- /dev/null +++ b/published/2007.04.04-a-triple-booting-schizophrenic-macbook.md @@ -0,0 +1,37 @@ +Title: A triple-booting, schizophrenic MacBook +Date: April 4, 2007 +Timestamp: 1175754600 +Author: sjs +Tags: linux, mac os x, windows +---- + +The steps are well documented so I won’t get into detail here but if you have a backup and can wipe your disk all you do is: + + * Install OS X to a single partition filling your disk (optionally use your existing OS X intall) + * Install rEFIt (no need to reboot just yet) + * Re-partition your disk into 3 partitions with diskutil resizeVolume, reboot and confirm it all works + * Boot the Vista install DVD and install to disk0s4 aka Partition 4 + * Install Gentoo (or other distro) to disk0s3 aka /dev/sda3 + +With MacPorts and Gentoo/MacOSX the Gentoo install is superfluous but I’ll spare 12G just to see Gentoo run on this fine machine. Setting up the hardware should be fun. Right now I’m compiling X, (package 77 of 94) and the Core Duo is crunching code very nicely with 2G to work with, without any swap. I fully intend to put off creating a swap file unless I have to. Needless to say I’ll be running fluxbox or Xfce, none of that Gnome or KDE stuff. If I ever need a swap file I will eat my keyboard. + +*[edit: 25 minutes to compile X.org, not too shabby!]* + +My initial experience with Vista is quite good. Sadly the same old registry hack is required to swap Caps lock and Control but I was just glad it worked. I really like the new Start menu and the eye-candy is fairly pleasant for the most part. Till now I’d only used RC2 on a machine incapable of running Aero Glass and it looked terrible. I switched to Windows Classic just like I do with XP. Not so with Aero at its finest though. Without thinking about the price Vista is a nice upgrade to Windows. But because of the price and uncertainty of running Aero Glass I still hesitate to urge non-geeks to upgrade. + +OS X is OS X. It’s my favourite desktop OS right now because of apps like LaunchBar/Quicksilver and TextMate, a generally excellent UI, good old *nix stability, zsh out of the box! When I need WireShark or the GIMP X11 is there waiting. Mac notebooks are great and tight integration with the hardware is a clear advantage for OS X. + +Oh yeah, I also have a Parallels VM for Windows 3.11. It boots in about second to the C:\> prompt and then another second to type win and Windows to start. Without TCP/IP there’s not much to do though (I’m not going to write a driver for Parallels’ ethernet adapter). + +
    +
  1. + + back up ↑ +
+ +Like I said the X.org boys are doing amazing work. Hopefully soon after the current eye-candy craze is over they’ll get to more important work that needs to be done. diff --git a/published/2007.04.16-getting-to-know-vista.md b/published/2007.04.16-getting-to-know-vista.md new file mode 100644 index 0000000..0eeffa1 --- /dev/null +++ b/published/2007.04.16-getting-to-know-vista.md @@ -0,0 +1,64 @@ +Title: Getting to know Vista +Date: April 16, 2007 +Timestamp: 1176746940 +Author: sjs +Tags: windows +---- + +### It looks pretty good! ### + +After figuring out how to minimise the translucency of the window decorations I think Aero looks ok. Window titles, on both windows and the taskbar, can be difficult to read at a glance which is really stupid if you ask me. But it’s better than Luna! They really lay the effects on thick but overall I find it pretty pleasant and it runs well on my MacBook’s Intel 945 video chip. + +Ah yes, the Sidebar is nowhere to be seen on my desktop. It’s a nice-looking waste of space. + +### But it’s not all useful ### + +Sadly The new task switcher (Win-tab) is terrible. Before using it I wondered why they didn’t replace Alt-tab completely. Now I know and I am grateful to MS for not replacing it. Alt-tab easily wins. Especially since it displays thumbnails of windows. + +Three gripes with Win-tab fancy-shmanciness: + + * It’s too slow + * It responds even when I just tap Win-tab to quickly switch, then I’m stuck until I hit the Windows key to choose a window + * Windows from all my monitors are gathered onto the main one, which is just lame + +### It’s stable (so far) ### + +Besides the fact it is aesthetically pleasing [subjective] it also has just worked for me so far. Nothing has crashed or broken which is almost miraculous. Not that I had a terrible time with XP, but it was still frail old Windows at times. I’m equally pleased with Apple’s drivers for Windows which probably adds to the experience. I’ve used XP machines with proper drivers, and those without and the differenc is night & day. I’ve had uptimes in months on a stable XP notebook. + + +### Never thought this day would come... ### + +But I actually like the Start menu. Really, I do. You hit the Windows key, type a few letters and boom you launch your app or search your computer, or the web (Google in Firefox, my default search). It’s not QuickSilver or LaunchBar; it’s not supposed to be. For the average Joe this is cool, and for the average power user it’s very useful. For the casual Windows user it’s great. It even learns. + +I don’t love it though. I knew before using it that the new method of navigating through the All Programs menu would be weird. It is, but I guess it may be better than the previous fly-out scheme (which I don’t care for either). I guess the All Programs menu is more or less legacy now though and I don’t see myself using it often. + + +### I’m a command line junkie ### + +They fixed at least one glaring bug. I used the cmd.exe shell a little bit even though I hate it. I was happy to find that Tab completion works for more than the current directory now. Before Vista it would complete the same entries from PWD no matter how deep you tried to drill down into the filesystem. Other than that it seems to be the same crummy shell. *[edit—apparently this is fixed in XP as well, my mistake]* + +I installed the Windows PowerShell (PoSH) but haven’t really put an effort to learn it yet. The syntax is unorthodox coming from *nix shells (zsh), but it’s sort of refreshing and it lives up to the Power part of its name. I really like the fact that collections of (say) files can be passed around and iterated over, filtered, etc. not as filenames but as real objects with corresponding methods and metadata. Built-in support for XML is pretty nifty too. + +I’ve often longed for a shell which acted like a normal shell for the most part, but allowed irb-like interpretation of arbitrary Ruby code as well. The PowerShell seems like it could be something similar to what I’ve wanted. Too bad it’s proprietary and only runs on Windows. If I use Vista a lot this summer I could end up getting into it more though. It’s quite interesting. + +### Random ### + +The good: + + * Slideshow button in Explorer + * Doesn’t look like a Fisher-Price design + * Restarts when I click Restart (after 3 clicks it damn well better) + * Seems stable, at least initially which means the installation & driver situation really has improved + * I don’t want to kill anyone while using it + +The bad: + + * Flicker while changing video modes, displaying UAC prompts, etc. (not so bad really, but stands out on an otherwise smooth desktop) + * Long black screen on boot after installing updates + * Disappearing / magical menu bar debacle + * The shell still sucks + * It tries to be too fancy, with the dynamic Start menu icon and the like + +### My conclusion ### + +Perhaps the scores of talented developers at Microsoft *can* save them despite their obvious shortcomings in management. .NET seems like a decent platform, but we’ll have to see how I like it once I actually use it. So far I don’t hate Vista and considering the previous versions of Windows that’s a pretty good review coming from me. I’m still recommending Macs to my family and friends, but who knows what the future holds. I don’t hate Vista and by the end of the summer I may even [gasp] like it, and/or .NET. I haven’t used an IDE since VB6 and MS has always had a decent IDE (albeit with a crummy text editor). I’m expecting to enjoy it. If there’s one thing MS knows it’s the value of good dev tools and developers. diff --git a/published/2007.04.26-quickly-inserting-millions-of-rows-with-mysql-innodb.md b/published/2007.04.26-quickly-inserting-millions-of-rows-with-mysql-innodb.md new file mode 100644 index 0000000..cedc573 --- /dev/null +++ b/published/2007.04.26-quickly-inserting-millions-of-rows-with-mysql-innodb.md @@ -0,0 +1,52 @@ +Title: Quickly inserting millions of rows with MySQL/InnoDB +Date: April 26, 2007 +Timestamp: 1177596360 +Author: sjs +Tags: linux, mysql +---- + +The absolute first thing you should do is check your MySQL configuration to make sure it’s sane for the system you’re using. I kept getting a ‘The table is too large’ error on my Gentoo box after inserting several million rows because the default config limits the InnoDB tablespace size to 128M. It was also tuned for a box with as little as 64M of RAM. That’s cool for a small VPS or your old Pentium in the corner collecting dust. For a modern server, workstation, or even notebook with gigs of RAM you’ll likely want to make some changes. + +### Tweaking my.cnf ### + +Here are the relevant settings you can tweak in order to work with large datasets efficiently. These are set in your my.cnf file, which varies in location. + +On Gentoo it resides at /etc/mysql/my.cnf. + +When MySQL 5.x is installed via DarwinPorts on Mac OS X you need to copy one of the defaults from /opt/local/share/mysql5/mysql/ to /opt/local/etc/mysql5/my.cnf and then modify it accordingly. + +If you use another system you’re on your own. If you can’t figure it out, please put down the text editor and leave the poor config file alone! Jokes aside this really is not difficult if you’re used to configuring *nix programs. + +### innodb_buffer_pool_size ### + +This determines how much memory MySQL uses for table indexes and data. You can set it as low as 8-10M, or high as 50-80% of your memory on a dedicated MySQL server. I have RAM to burn[1] in my workstation so I set this to 200M, 20% of my 1GB. + +[1] I run Fluxbox on Gentoo, I use 200-300M of my 1GB on average and with 200M for MySQL 409M are in use at this moment. Gotta love those lightweight window managers! + +### innodb_additional_mem_pool_size ### + +According to [a post on a MySQL mailing list](http://lists.mysql.com/mysql/129247), modern OSs have fast enough mallocs and this variable has little effect on performance. I set mine to 16M before reading that post, so I’ll just leave it at that. + +### innodb_data_file_path ### + +On Gentoo this one bit me right in the ass, and I mentioned it above. It specifies how large the files used to store your data can be, and how many of them there are. The default setting is almost sane: ibdata1:10M:autoextend:max:128M. Limiting the total size to 128M caused my test to fail after inserting several million rows. + +Simply removing max:128M solves the problem. The resulting setting tells the InnoDB engine to use one file, named ibdata1 which is initially 10M in size and grows as required. + +### innodb_log_file_size ### + +The default Gentoo config says they (whoever they are) keep this at 25% of innodb_buffer_pool_size so I did just that. 50M in my case. + +### innodb_log_buffer_size ### + +Again I only went as far as the Gentoo config to learn about this setting. They had it at 8M and recommend increasing it if you have large transactions. I can’t think of any particularly large transactions I currently use but I doubled it to 16M anyway. + +### Save my.cnf and restart mysqld ### + +That’s it for the MySQL config. Restart mysqld however you do that on your platform. sudo /etc/init.d/mysql restart should look familiar to many *nix users. + +Now you should be able to insert dozens and indeed hundreds of millions of rows into your InnoDB tables. Sadly this brought little performance gains to the table. MySQL wraps single queries in implicit transactions. Wrapping everything in a transaction may work, but inevitably something will go wrong and you may want the ability to resume inserting the rows instead of starting all over. + +The solution now is to execute SET AUTOCOMMIT=0 before inserting the data, and then issuing a COMMIT when you’re done. With all that in place I’m inserting 14,000,000 rows into both MyISAM and InnoDB tables in 30 minutes. MyISAM is still ~ 2 min faster, but as I said earlier this is adequate for now. Prior to all this it took several hours to insert 14,000,000 rows so I am happy. + +Now you can enjoy the speed MyISAM is known for with your InnoDB tables. Consider the data integrity a bonus! ;-) diff --git a/published/2007.04.30-funny-how-code-can-be-beautiful.md b/published/2007.04.30-funny-how-code-can-be-beautiful.md new file mode 100644 index 0000000..154b158 --- /dev/null +++ b/published/2007.04.30-funny-how-code-can-be-beautiful.md @@ -0,0 +1,25 @@ +Title: Funny how code can be beautiful +Date: April 30, 2007 +Timestamp: 1177942020 +Author: sjs +Tags: haskell +---- + +While reading a Haskell tutorial I came across the following code for defining the Fibonacci numbers: + + fib = 1 : 1 : [ a + b | (a, b) <- zip fib (tail fib) ] + +After reading it a few times and understanding how it works I couldn’t help but think how beautiful it is. I don’t mean that it’s aesthetically pleasing to me; the beautiful part is the meaning and simplicity. Lazy evaluation is sweet. + +Haskell is the most challenging real language I have tried to wrap my head around. I haven’t done much with any functional languages yet but they are truly fascinating. I’m beginning to understand monads[1] but I’m quite sure I don’t see the whole picture yet. + +Erlang looks like it may be more suited to real world apps so I would like to learn that some time. The pragmatic guys have a book on Erlang in the works, and I love every book of theirs which I have read. + +Going deeper down the functional rabbit-hole you’ll find things like this polyglot quine, which absolutely blows my mind. I used to be impressed by the JAPH sigs or some of the various obfuscated contest winners but that first one definitely cleans the rest up with a perfect 10 in geekiness. + +[1] The following links have all been helpful while trying to wrap my head around monads. + + * A Gentle Introduction to Haskell (link is directly to chapter 9) + * What the hell are Monads? + * Monads on WikiBooks + * Monads for the Working Haskell Programmer diff --git a/published/2007.05.01-typo-and-i-are-friends-again.md b/published/2007.05.01-typo-and-i-are-friends-again.md new file mode 100644 index 0000000..76243a1 --- /dev/null +++ b/published/2007.05.01-typo-and-i-are-friends-again.md @@ -0,0 +1,14 @@ +Title: Typo and I are friends again +Date: May 1, 2007 +Timestamp: 1178081497 +Author: sjs +Tags: typo +---- + +

I've been really frustrated with Typo recently. For some reason changing my last post would cause MySQL to timeout and I'd have to kill the rogue ruby process manually before any other changes to the DB would work, instead of hanging for a minute or two then timing out. Luckily I was able to disable the post using the command line client, the bug only manifested itself when issuing an UPDATE with all the fields present. Presumably the body was tripping things up because most other fields are simple booleans, numbers, or very short strings. + +Add to that the random HTTP 500 errors which were very noticeable while I was trying to fix that post and I was about to write my own blog or switch to WordPress. + +I don't love WP so I decided to just upgrade Typo instead. I was using Typo 2.6, and the current stable version is 4.1. They skipped version 3 to preclude any confusion that may have ensued between Typo v3 and the CMS Typo3. So it really isn't a big upgrade and it went perfectly. I checked out a new copy of the repo because I had some difficulty getting svn switch --relocate to work, configured the database settings and issued a rake db:migrate, copied my theme over and it all just worked. Bravo Typo team, that's how an upgrade should work. + +No more random 500 errors, things seem faster (better caching perhaps), and that troublesome post is troublesome no more. I am happy with Typo again. diff --git a/published/2007.05.03-a-scheme-parser-in-haskell-part-1.md b/published/2007.05.03-a-scheme-parser-in-haskell-part-1.md new file mode 100644 index 0000000..09a34a8 --- /dev/null +++ b/published/2007.05.03-a-scheme-parser-in-haskell-part-1.md @@ -0,0 +1,67 @@ +Title: A Scheme parser in Haskell: Part 1 +Date: May 3, 2007 +Timestamp: 1178178470 +Author: sjs +Tags: coding, haskell +---- + +From Write Yourself a Scheme in 48 hours: + +

+

Basically, a monad is a way of saying "there's some extra information attached to this value, which most functions don't need to worry about". In this example, the "extra information" is the fact that this action performs IO, and the basic value is nothing, represented as "()". Monadic values are often called "actions", because the easiest way to think about the IO monad is a sequencing of actions that each might affect the outside world.

+
+ +I really like this tutorial. I'm only on part 3.3 of 12, parsing, but I'm new to Haskell so I'm learning left, right & centre. The exercises are taking me hours of reading and experimenting, and it's lots of fun! ghc's errors are usually quite helpful and of course ghci is a big help as well. + +I'm going to explain one of the exercises because converting between the various syntax for dealing with monads wasn't plainly obvious to me. Perhaps I wasn't paying enough attention to the docs I read. In any case if you're interested in Haskell at all, I recommend the tutorial and if you're stuck on exercise 3.3.1 like I was then come on back here. Whether you're following the tutorial or not the point of this post should stand on its own with a basic knowledge of Haskell. + +Last night I rewrote parseNumber using do and >>= (bind) notations (ex. 3.3.1). Here's parseNumber using the liftM method given in the tutorial: + +
parseNumber :: Parser LispVal
+parseNumber :: liftM (Number . read) $ many1 digit
+
+Okay that's pretty simple right? Let's break it down, first looking at the right-hand side of the $ operator, then the left. + + * many1 digit reads as many decimal digits as it can. + * Number . read is a function composition just like we're used to using in math. It applies read to its argument, then applies Number to that result. + * liftM is concisely and effectively defined elsewhere, and I'll borrow their description: + +
+

liftM f m lets a non-monadic function f operate on the contents of monad m

+
+ +liftM's type is also quite telling: liftM :: (Monad m) => (a -> b) -> (m a -> m b) + +In a nutshell liftM turns a function from a to b to a function from a monad containing a to a monad containing b. + +That results in a function on the left-hand side of $, which operates on and outputs a monad. The content of the input monad is a String. The content of the output monad is a LispVal (defined earlier in the tutorial). Specifically it is a Number. + +The $ acts similar to a pipe in $FAVOURITE_SHELL, and is right associative which means the expression on the right is passed to the expression (function) on the left. It's exactly the same as (liftM (Number . read)) (many1 digit) except it looks cleaner. If you know LISP or Scheme (sadly I do not) then it's analogous to the apply function. + +So how does a Haskell newbie go about re-writing that using other notations which haven't even been explained in the tutorial? Clearly one must search the web and read as much as they can until they understand enough to figure it out (which is one thing I like about the tutorial). If you're lazy like me, here are 3 equivalent pieces of code for you to chew on. parseNumber's type is Parser LispVal (Parser is a monad). + + +Familiar liftM method: +
parseNumber -> liftM (Number . read) $ many1 digit
+
+ +Using do notation: +
parseNumber -> do digits <- many1 digit
+                  return $ (Number . read) digits
+
+If you're thinking "Hey a return, I know that one!" then the devious masterminds behind Haskell are certainly laughing evilly right now. return simply wraps up it's argument in a monad of some sort. In this case it's the Parser monad. The return part may seem strange at first. Since many1 digit yields a monad why do we need to wrap anything? The answer is that using <- causes digits to contain a String, stripped out of the monad which resulted from many1 digit. Hence we no longer use liftM to make (Number . read) monads, and instead need to use return to properly wrap it back up in a monad. + +In other words liftM eliminates the need to explicitly re-monadize the contents as is necessary using do. + + +Finally, using >>= (bind) notation: +
parseNumber -> many1 digit >>= \digits ->
+               return $ (Number . read) digits
+
+At this point I don't think this warrants much of an explanation. The syntactic sugar provided by do should be pretty obvious. Just in case it's not, >>= passes the contents of its left argument (a monad) to the function on its right. Once again return is needed to wrap up the result and send it on its way. + +When I first read about Haskell I was overwhelmed by not knowing anything, and not being able to apply my previous knowledge of programming to anything in Haskell. One piece of syntax at a time I am slowly able to understand more of the Haskell found in the wild. + +I'm currently working on ex. 3.3.4, which is parsing R5RS compliant numbers (e.g. #o12345670, #xff, #d987). I'll probably write something about that once I figure it out, but in the meantime if you have any hints I'm all ears. + +*Update #1: I should do more proof-reading if I'm going to try and explain things. I made some changes in wording.* diff --git a/published/2007.06.08-so-long-typo-and-thanks-for-all-the-timeouts.md b/published/2007.06.08-so-long-typo-and-thanks-for-all-the-timeouts.md index 6741554..12e9d7c 100644 --- a/published/2007.06.08-so-long-typo-and-thanks-for-all-the-timeouts.md +++ b/published/2007.06.08-so-long-typo-and-thanks-for-all-the-timeouts.md @@ -7,7 +7,7 @@ Tags: mephisto, typo Well for just over a year Typo ran the show. I thought I had worked out most of the kinks with Typo and Dreamhost but the latest problem I ran into was pretty major. I couldn't post new articles. If the stars aligned perfectly and I sacrificed baby animals and virgins, every now and then I could get it to work. Ok, all I really had to do was refresh several dozen times, waiting 1 minute for it to timeout every time, but it sucked nonetheless. -Recently I had looked at converting Typo to Mephisto and it seemed pretty painless. I installed Mephisto and followed whatever instructions I found via Google and it all just worked, with one caveat. The Typo converter for Mephisto only supports Typo's schema version 56, while my Typo schema was at version 61. Rather than migrate backwards I brought Mephisto's Typo converter up to date instead. If you're interested, download the patch. The patch is relative to vendor/plugins, so patch accordingly. +Recently I had looked at converting Typo to Mephisto and it seemed pretty painless. I installed Mephisto and followed whatever instructions I found via Google and it all just worked, with one caveat. The Typo converter for Mephisto only supports Typo's schema version 56, while my Typo schema was at version 61. Rather than migrate backwards I brought Mephisto's Typo converter up to date instead. If you're interested, download the patch. The patch is relative to vendor/plugins, so patch accordingly. After running that code snippet to fix my tags, I decided to completely ditch categories in favour of tags. I tagged each new Mephisto article with a tag for each Typo category it had previously belonged to. I fired up RAILS_ENV=production script/console and typed something similar to the following: diff --git a/published/2007.06.15-begging-the-question.md b/published/2007.06.15-begging-the-question.md index 7c0807f..5aee8b2 100644 --- a/published/2007.06.15-begging-the-question.md +++ b/published/2007.06.15-begging-the-question.md @@ -5,11 +5,11 @@ Author: sjs Tags: english, life, pedantry ---- -I'm currently reading SICP since it's highly recommended by many people, available for free, and interesting. The fact that I have a little Scheme interpreter to play with makes it much more fun since I can add missing functionality to it as I progress through the book, thereby learning more Haskell in the process. Yay! +I'm currently reading SICP since it's highly recommended by many people, available for free, and interesting. The fact that I have a little Scheme interpreter to play with makes it much more fun since I can add missing functionality to it as I progress through the book, thereby learning more Haskell in the process. Yay! Anyway I was very pleased to see the only correct usage of the phrase "begs the question" I have seen in a while. It's a pet peeve of mine, but I have submitted myself to the fact that the phrase is so oft used to mean "begs for the following question to be asked..." that it may as well be re-defined. In its correct usage the sentence seems to hang there if you try to apply the commonly mistaken meaning to it. That's all very hazy so here's the usage in SICP (emphasis my own): -
As a case in point, consider the problem of computing square roots. We can define the square-root function as +
As a case in point, consider the problem of computing square roots. We can define the square-root function as √x = the y such that y ≥ 0 and y² = x This describes a perfectly legitimate mathematical function. We could use it to recognize whether one number is the square root of another, or to derive facts about square roots in general. On the other hand, the definition does not describe a procedure. Indeed, it tells us almost nothing about how to actually find the square root of a given number. It will not help matters to rephrase this definition in pseudo-Lisp: diff --git a/published/2007.08.02-elschemo-boolean-logic-and-branching.md b/published/2007.08.02-elschemo-boolean-logic-and-branching.md index bcd4deb..8d7ddab 100644 --- a/published/2007.08.02-elschemo-boolean-logic-and-branching.md +++ b/published/2007.08.02-elschemo-boolean-logic-and-branching.md @@ -7,7 +7,7 @@ Tags: elschemo, haskell, scheme I've been developing a Scheme interpreter in Haskell called -ElSchemo. +ElSchemo. It started from Jonathan's excellent Haskell tutorial which I followed in order to learn both Haskell and Scheme. Basically diff --git a/wayback/@done/Apple pays attention to detail - samhuri.net.html b/wayback/@done/Apple pays attention to detail - samhuri.net.html new file mode 100644 index 0000000..5b6be10 --- /dev/null +++ b/wayback/@done/Apple pays attention to detail - samhuri.net.html @@ -0,0 +1,542 @@ + + + + Apple pays attention to detail - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

Apple pays attention to detail

+

+ Sun, 11 Jun 2006 08:30:00 GMT

+

I think this has to be one of the big reasons why people who love their Mac, love their Mac (or other Apple product). I usually just have cheap PC speakers plugged into my Mac mini, but I didn’t bring any with me to Munich and the internal Mac mini speaker isn’t very loud, so I’m using headphones to watch movies. My Mac remembers the volume setting when the headphones ore plugged in, and when they’re not, so I don’t accidentally blow my ears. It’s like my iPod pausing when the headphones are unplugged. It’s excruciating attention to the smallest, (seemingly) most unimportant detail. I love it, and I’m hooked.

+
+

+ Posted in , ,  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/426 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo - samhuri.net.html b/wayback/@done/Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo - samhuri.net.html new file mode 100644 index 0000000..8c783c9 --- /dev/null +++ b/wayback/@done/Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo - samhuri.net.html @@ -0,0 +1,545 @@ + + + + Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo

+

+ Sun, 17 Sep 2006 05:11:00 GMT

+

Wouldn’t the sentence ‘I want to put a hyphen between the words Fish and And and And and Chips in my Fish-And-Chips sign’ have been clearer if quotation marks had been placed before Fish, and between Fish and and, and and and And, and And and and, and and and And, and And and and, and and and Chips, as well as after Chips?

+ + +

Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo

+
+

+ Posted in  | Tags  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/437 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/Class method Instance method It doesn't matter to PHP - samhuri.net.html b/wayback/@done/Class method Instance method It doesn't matter to PHP - samhuri.net.html new file mode 100644 index 0000000..1241391 --- /dev/null +++ b/wayback/@done/Class method Instance method It doesn't matter to PHP - samhuri.net.html @@ -0,0 +1,593 @@ + + + + Class method? Instance method? It doesn't matter to PHP - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

Class method? Instance method? It doesn't matter to PHP

+

+ Fri, 21 Jul 2006 14:56:00 GMT

+

Update: This has been discussed for PHP6. A little late, but I guess better than never.

+ + +

I made a mistake while I was coding, for shame! Anyway this particular mistake was that I invoked a class method on the wrong class. The funny part was that this method was an instance method in the class which I typed by mistake. In the error log I saw something like “Invalid use of $this in class function.”

I knew for a fact I hadn’t used $this in a class method, so it was kind of a confusing error. I went to the file in question and found out that it was calling an instance method as a class method. Now that is some crazy shit.

+ + +

I would fully expect the PHP parser to give me an error like “No class method [foo] in class [blah]”, rather than try and execute it as a class method. The syntax is completely different; you use :: to call a class method and -> to call an instance method. And you use the name of a class when you call a class method.

+ + +

This code:

+ + +

+class Foo {
+  public static function static_fun()
+  {
+    return "This is a class method!\n";
+  }
+
+  public function not_static()
+  {
+    return "This is an instance method!\n";
+  }
+}
+
+echo '<pre>';
+echo "From Foo:\n";
+echo Foo::static_fun();
+echo Foo::not_static();
+echo "\n";
+
+echo "From \$foo = new Foo():\n";
+$foo = new Foo();
+echo $foo->static_fun();
+echo $foo->not_static();
+echo '</pre>';
+
+ +

Produces:

+ + +
+From Foo:
+This is a class method!
+This is an instance method!
+
+From $foo = new Foo():
+This is a class method!
+This is an instance method!
+
+ +

What the fuck?! http://www.php.net/manual/en/language.oop5.static.php is lying to everyone.

+
+

+ Posted in ,  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/431 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/I don't mind FairPlay either - samhuri.net.html b/wayback/@done/I don't mind FairPlay either - samhuri.net.html new file mode 100644 index 0000000..2b9abec --- /dev/null +++ b/wayback/@done/I don't mind FairPlay either - samhuri.net.html @@ -0,0 +1,544 @@ + + + + I don't mind FairPlay either - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

I don't mind FairPlay either

+

+ Sat, 04 Mar 2006 05:56:00 GMT

+

I think that Jim is right about Apple’s DRM not being all that evil.

+ + +

I buy music from the iTunes Music Store because I bought an iPod. The fact I can’t play them on another device doesn’t matter to me. With my purchased songs I can:

+ + +
    +
  • listen to the songs I buy all I want
  • +
  • burn them to CD
  • +
  • stream them to my amplifier via AirPort Express
  • +
+ + +

I don’t buy a ton of music from the iTMS, but I can’t tell the difference between any of those songs and the songs I ripped from CDs and they’re all mixed in one collection. That’s good enough for me.

+ + +

I dislike DRM as much as the next guy, but like CSS encryption on DVDs, FairPlay is something I can live with.

+ + +

It reminds me of how here in North America I have to live with the crappy cell phone companies that lock their phones to their networks. If it’s something I need or want, sometimes I’ll live with restrictions because there are no alternatives yet.

+ + +

Update: It’s almost settled. The pope got an iPod so all that’s left is to see if he buys any music off of iTunes. If he does, then it can’t be evil. heh…

+
+

+ Posted in , ,  | Tags , , ,  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/37 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/Late static binding - samhuri.net.html b/wayback/@done/Late static binding - samhuri.net.html new file mode 100644 index 0000000..d49abca --- /dev/null +++ b/wayback/@done/Late static binding - samhuri.net.html @@ -0,0 +1,601 @@ + + + + Late static binding - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

Late static binding

+

+ Wed, 19 Jul 2006 17:23:00 GMT

+

Update: This has been discussed and will be uh, sort of fixed, in PHP6. You’ll be able to use static::my_method() to get the real reference to self in class methods. Not optimal, but still a solution I guess.

+ + +

As colder on ##php (freenode) told me today, class methods in PHP don’t have what they call late static binding. What’s that? It means that this code:

+ + +
+
+class Foo
+{
+  public static function my_method()
+  {
+    echo "I'm a " . get_class() . "!\n";
+  }
+}
+
+class Bar extends Foo
+{}
+
+Bar::my_method();
+
+
+ +

outputs “I’m a Foo!”, instead of “I’m a Bar!”. That’s not fun.

Using __CLASS__ in place of get_class() makes zero difference. You end up with proxy methods in each subclass of Foo that pass in the real name of the calling class, which sucks.

+ + +
+
+class Bar extends Foo
+{
+  public static function my_method()
+  {
+    return parent::my_method( get_class() );
+  }
+}
+
+
+ +

I was told that they had a discussion about this on the internal PHP list, so at least they’re thinking about this stuff. Too bad PHP5 doesn’t have it. I guess I should just be glad I won’t be maintaining this code.

+ + +

The resident PHP coder said “just make your code simpler”, which is what I was trying to do by removing duplication. Too bad that plan sort of backfired. I guess odd things like this are where PHP starts to show that OO was tacked on as an after-thought.

+
+

+ Posted in ,  | Tags ,  | 2 comments | no trackbacks +

+ +

Comments

+ +
    + +
  1. + + + Avatar + Jim Roepcke said 25 days later:
    +

    That’s the worst of both worlds.

    + + +

    In Objective-C, that would work properly. In Java, it wouldn’t work at all because static methods (Java doesn’t have class methods) aren’t inherited by subclasses, so at least if you called the method on the superclass the result would be consistent…. but this, this crap (as PHP always is), well, it isn’t consistent with anything. Doesn’t get any worse. But, I’m hardly surprised.

    +
  2. + + + Avatar + Sami said 34 days later:
    +

    Interesting about Java, I didn’t know static methods weren’t inherited.

    + + +

    I have to say that I don’t know if I can work another job using PHP and keep my sanity. :)

    +
  3. + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/430 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/OS X and Fitt's law - samhuri.net.html b/wayback/@done/OS X and Fitt's law - samhuri.net.html new file mode 100644 index 0000000..03693fd --- /dev/null +++ b/wayback/@done/OS X and Fitt's law - samhuri.net.html @@ -0,0 +1,522 @@ + + + + OS X and Fitt's law - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

OS X and Fitt's law

+

+ Mon, 08 May 2006 03:43:00 GMT

+

I’ve realized that OS X really does obey Fitt’s law in all 4 corners now. Apple menu in the top left, Spotlight top right, and the bottom 2 are always accessible for drag n drop, unless the dock is hidden. I rarely ever use it because I usually have pretty good chunks of the desktop showing, but it is useful.

+
+

+ Posted in ,  | Tags , , ,  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/65 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/Ruby and Rails have spoiled me rotten - samhuri.net.html b/wayback/@done/Ruby and Rails have spoiled me rotten - samhuri.net.html new file mode 100644 index 0000000..1d147bb --- /dev/null +++ b/wayback/@done/Ruby and Rails have spoiled me rotten - samhuri.net.html @@ -0,0 +1,551 @@ + + + + Ruby and Rails have spoiled me rotten - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

Ruby and Rails have spoiled me rotten

+

+ Mon, 17 Jul 2006 12:40:00 GMT

+

It’s true. I’m sitting here coding in PHP using the Zend Framework and all I can think about is how much nicer Rails is, or how much easier it is to do [x] in Ruby. It’s not that the Zend Framework is bad or anything, it’s quite nice, but you just can’t match Ruby’s expressiveness in a language like PHP. Add the amazing convenience Rails builds on top of Ruby and that’s a really hard combo to compete with.

I’d love to be using mixins instead of mucking around with abstract classes and interfaces, neither of which will just let you share a method between different classes. Writing proxy methods in these tiny in-between classes is annoying. (ie. inherit from Zend_class, then my real classes inherit from the middle-man class) I could add things to Zend’s classes, but then upgrades are a bitch. I miss Ruby. I could use something like whytheluckystiff’s PHP mixins, which is a clever hack, but still a hack.

+ + +

I keep looking at Rails code to see how things are done there, and I already coded a nearly complete prototype in Rails as a reference. I could have finished the thing in Rails by now, seriously. I’m still playing catch-up writing validations and model classes for all my objects, stuff I could’ve had for free using Rails, with an extra 10 mins to add validations and make sure they’re all working nicely.

+ + +

It’s no wonder David H. Hansson wasn’t able to write a framework he was happy with in PHP. After using Rails everything seems like a chore. I’m just coding solved problems over again in an inferior language.

+ + +

But hey, I’m learning things and I still got to use Ruby even if the code won’t be used later. I guess this experience will just make me appreciate the richness of Ruby and Rails even more.

+
+

+ Posted in , , ,  | Tags , , , ,  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/429 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/SJ's Rails Bundle 0.2 for TextMate - samhuri.net.html b/wayback/@done/SJ's Rails Bundle 0.2 for TextMate - samhuri.net.html new file mode 100644 index 0000000..272ae2b --- /dev/null +++ b/wayback/@done/SJ's Rails Bundle 0.2 for TextMate - samhuri.net.html @@ -0,0 +1,594 @@ + + + + SJ's Rails Bundle 0.2 for TextMate - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

SJ's Rails Bundle 0.2 for TextMate

+

+ Fri, 24 Feb 2006 01:18:00 GMT

+

Everything that you’ve seen posted on my blog is now available in one bundle. Snippets for Rails database migrations and assertions are all included in this bundle.

+ + +

There are 2 macros for class-end and def-end blocks, bound to ⌃C and ⌃D respectively. Type the class or method definition, except for class or def, and then type the keyboard shortcut and the rest is filled in for you.

+ + +

I use an underscore to denote the position of the cursor in the following example:

+ + +
method(arg1, arg2_)
+ +

Typing ⌃D at this point results in this code:

+ + +
def method(arg1, arg2)
+  _
+end
+ +

There is a list of the snippets in Features.rtf, which is included in the disk image. Of course you can also browse them in the Snippets Editor built into TextMate.

+ + +

Without further ado, here is the bundle:

+ + +

Download Download SJ’s Rails Bundle 0.2

+ + +

This is a work in progress, so any feedback you have is very helpful in making the next release better.

+
+

+ Posted in , ,  | Tags , , , ,  | 3 comments | no trackbacks +

+ +

Comments

+ +
    + +
  1. + + + Avatar + Duane Johnson said 3 days later:
    +

    Hi Sami! I’ve added your superb work to the Rails bundle itself. I love it! Thanks again.

    + + +

    Release candidate 4: +http://blog.inquirylabs.com/

    +
  2. + + + Avatar + Duane Johnson said 8 days later:
    +

    With the inspiration of Scott Barron (and a tip from Kyle Maxwell) I’ve added the reverse migration to the Rails bundle also. You can now use the “mdct” snippet and it will create the corresponding table for the drop_table, using your db/schema.rb as source material. Only in SVN at this point.

    +
  3. + + + Avatar + Sami said 8 days later:
    +

    That’s excellent! I added the ability to reverse the snippets just yesterday, but I never thought to get data from schema.rb to do it in that clever way.

    + + +

    I’ll have to take a look at it. Thanks. :)

    +
  4. + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/29 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/Spore - samhuri.net.html b/wayback/@done/Spore - samhuri.net.html new file mode 100644 index 0000000..384401a --- /dev/null +++ b/wayback/@done/Spore - samhuri.net.html @@ -0,0 +1,525 @@ + + + + Spore - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

Spore

+

+ Sat, 04 Mar 2006 05:43:00 GMT

+

This game that Jim blogged about is probably the coolest game I’ve seen.

+ + +

You really just have to watch the video, I won’t bother explaining it here. I don’t really play games much, but this I would play.

+
+

+ Posted in ,  | Tags , ,  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/36 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/Where are my headphones - samhuri.net.html b/wayback/@done/Where are my headphones - samhuri.net.html new file mode 100644 index 0000000..85301c7 --- /dev/null +++ b/wayback/@done/Where are my headphones - samhuri.net.html @@ -0,0 +1,556 @@ + + + + Where are my headphones? - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

Where are my headphones?

+

+ Tue, 22 Aug 2006 14:31:00 GMT

+

Some people left Seekport this month and 2 of the remaining employees moved into the office I’m working in. That’s fine, and I’m leaving at the end of the week, but man I’m going crazy. This guy’s pounding on his keyboard like it’s a fucking whack-a-mole game! I don’t know what kind of keyboard he learned to type on but it must’ve been horrible. It sounds like he must go through at least 10 of those things in a year. I don’t know if I’ll make it till Friday without yelling “AGH! STOP THE MADNESS YOU CRAZY BASTARD YOU JUST HAVE TO TOUCH THE KEYS!”

+
+

+ Posted in  | Tags  | 2 comments | no trackbacks +

+ +

Comments

+ +
    + +
  1. + + + Avatar + emil.eberhardt@amperegeruch.de said 1 day later:
    +

    Sami, obviously you are right, but I think you will survive the next few days. If you can’t withstand that noise you could pour some sweet and sticky drink into his keyboard, or just kick it out of the window ;-) I have to find a way to survive +much longer … +
    Torsten

    +
  2. + + + Avatar + Sami said 3 days later:
    +

    I survived! :) It wasn’t all that bad really, but I do feel a little sorry for you.

    +
  3. + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/433 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/WikipediaFS on Linux, in Python - samhuri.net.html b/wayback/@done/WikipediaFS on Linux, in Python - samhuri.net.html new file mode 100644 index 0000000..e796cf3 --- /dev/null +++ b/wayback/@done/WikipediaFS on Linux, in Python - samhuri.net.html @@ -0,0 +1,525 @@ + + + + WikipediaFS on Linux, in Python - samhuri.net + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +

WikipediaFS on Linux, in Python

+

+ Mon, 08 May 2006 03:49:00 GMT

+

Till now I’ve been using my own version of pywikipedia for scripting MediaWiki, and it works well. But I read about WikipediaFS and had to check it out. It’s a user space filesystem for Linux that’s built using the Python bindings for FUSE. What it does is mounts a filesystem that represents your wiki, with articles as text files. You can use them just like any other files with mv, cp, ls, vim, and so on.

+ + +

There hasen’t been any action on that project for 13 months though, and it doesn’t work on my wiki (MediaWiki 1.4.15) so I’m going to try and make it work after I upgrade to MediaWiki 1.6.3 tonight. This will be pretty cool when it works. I haven’t looked at the code yet but it’s only 650 lines.

+
+

+ Posted in , ,  | Tags , , , ,  | no comments | no trackbacks +

+ +

Comments

+ +
    + + + +
+ +

Trackbacks

+

+ Use the following link to trackback from your own site:
+ http://sami.samhuri.net/articles/trackback/66 +

+ + + + +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

(leave url/email »)

+ +
+    + Preview comment + +
+
+
+ + +
+ +
+ +
+ + + +
+ + + + + + + + + + + + + + diff --git a/wayback/@done/sjs A Scheme parser in Haskell Part 1.html b/wayback/@done/sjs A Scheme parser in Haskell Part 1.html new file mode 100644 index 0000000..dff1fd2 --- /dev/null +++ b/wayback/@done/sjs A Scheme parser in Haskell Part 1.html @@ -0,0 +1,760 @@ + + + + sjs: A Scheme parser in Haskell: Part 1 + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + +
+

+ A Scheme parser in Haskell: Part 1 + +

+
+ Posted by sjs +
+on Thursday, May 03 +
+
+ From Write Yourself a Scheme in 48 hours: +
+

Basically, a monad is a way of saying “there’s some extra information attached to this value, which most functions don’t need to worry about”. In this example, the “extra information” is the fact that this action performs IO, and the basic value is nothing, represented as “()”. Monadic values are often called “actions”, because the easiest way to think about the IO monad is a sequencing of actions that each might affect the outside world.

+
+ + +

I really like this tutorial. I’m only on part 3.3 of 12, parsing, but I’m new to Haskell so I’m learning left, right & centre. The exercises are taking me hours of reading and experimenting, and it’s lots of fun! ghc’s errors are usually quite helpful and of course ghci is a big help as well.

+ + +

I’m going to explain one of the exercises because converting between the various syntax for dealing with monads wasn’t plainly obvious to me. Perhaps I wasn’t paying enough attention to the docs I read. In any case if you’re interested in Haskell at all, I recommend the tutorial and if you’re stuck on exercise 3.3.1 like I was then come on back here. Whether you’re following the tutorial or not the point of this post should stand on its own with a basic knowledge of Haskell.

+ + +

Last night I rewrote parseNumber using do and >>= (bind) notations (ex. 3.3.1). Here’s parseNumber using the liftM method given in the tutorial:

+ + +
parseNumber :: Parser LispVal
+parseNumber :: liftM (Number . read) $ many1 digit
+
+ +

Okay that’s pretty simple right? Let’s break it down, first looking at the right-hand side of the $ operator, then the left.

+ + +
    +
  • many1 digit reads as many decimal digits as it can.
  • +
+ + +
    +
  • Number . read is a function composition just like we’re used to using in math. It applies read to its argument, then applies Number to that result.
  • +
+ + +
    +
  • liftM is concisely and effectively defined elsewhere, and I’ll borrow their description:
  • +
+ + +
+

liftM f m lets a non-monadic function f operate on the contents of monad m

+
+ + +

liftM’s type is also quite telling: liftM :: (Monad m) => (a -> b) -> (m a -> m b)

+ + +

In a nutshell liftM turns a function from a to b to a function from a monad containing a to a monad containing b.

+ + +

That results in a function on the left-hand side of $, which operates on and outputs a monad. The content of the input monad is a String. The content of the output monad is a LispVal (defined earlier in the tutorial). Specifically it is a Number.

+ + +

The $ acts similar to a pipe in $FAVOURITE_SHELL, and is right associative which means the expression on the right is passed to the expression (function) on the left. It’s exactly the same as (liftM (Number . read)) (many1 digit) except it looks cleaner. If you know LISP or Scheme (sadly I do not) then it’s analogous to the apply function.

+ + +

So how does a Haskell newbie go about re-writing that using other notations which haven’t even been explained in the tutorial? Clearly one must search the web and read as much as they can until they understand enough to figure it out (which is one thing I like about the tutorial). If you’re lazy like me, here are 3 equivalent pieces of code for you to chew on. parseNumber’s type is Parser LispVal (Parser is a monad).

+ + +Familiar liftM method: +
parseNumber -> liftM (Number . read) $ many1 digit
+
+ +Using do notation: +
parseNumber -> do digits <- many1 digit
+                  return $ (Number . read) digits
+
+ +

If you’re thinking “Hey a return, I know that one!” then the devious masterminds behind Haskell are certainly laughing evilly right now. return simply wraps up it’s argument in a monad of some sort. In this case it’s the Parser monad. The return part may seem strange at first. Since many1 digit yields a monad why do we need to wrap anything? The answer is that using <- causes digits to contain a String, stripped out of the monad which resulted from many1 digit. Hence we no longer use liftM to make (Number . read) monads, and instead need to use return to properly wrap it back up in a monad.

+ + +

In other words liftM eliminates the need to explicitly re-monadize the contents as is necessary using do.

+ + +Finally, using >>= (bind) notation: +
parseNumber -> many1 digit >>= \digits ->
+               return $ (Number . read) digits
+
+ +

At this point I don’t think this warrants much of an explanation. The syntactic sugar provided by do should be pretty obvious. Just in case it’s not, >>= passes the contents of its left argument (a monad) to the function on its right. Once again return is needed to wrap up the result and send it on its way.

+ + +

When I first read about Haskell I was overwhelmed by not knowing anything, and not being able to apply my previous knowledge of programming to anything in Haskell. One piece of syntax at a time I am slowly able to understand more of the Haskell found in the wild.

+ + +

I’m currently working on ex. 3.3.4, which is parsing R5RS compliant numbers (e.g. #o12345670, #xff, #d987). I’ll probably write something about that once I figure it out, but in the meantime if you have any hints I’m all ears.

+ + +

Update #1: I should do more proof-reading if I’m going to try and explain things. I made some changes in wording.

+ +
+ +
+ +
Comments
+

Leave a response

+
+
    + +
  1. +
    + Edward Kmett – + May 11, 2007 @ 10:26 AM +
    +
    + In your above example, you can view return as another function in the chain of functions to apply, yielding: + +parseNumber = many1 digit >>= return . Number . read + +or + +parseNumber = do digits <- many1 digit; return . Number . read $ digits + +of course, this is just unrolling the definition of liftM, so its not surprising. +
    +
  2. + +
  3. +
    + sjs – + May 11, 2007 @ 10:26 AM +
    +
    + Ah, that makes perfect sense. Thanks for that. Every little bit helps my understanding of monads. +
    +
  4. + +
  5. +
    + anonymous – + May 29, 2007 @ 01:49 PM +
    +
    +

    You might also want to know that for monads,

    + + +
    liftM = fmap
    + + +

    This is useful (at least for me), because I have different intuitions for liftM and fmap:

    + + +

    I see liftM as a function lifting ordinary functions to monadic functions, while I think of (fmap f) as a function manipulating the “contents” of a monadic value using f, just like the ordinary map on lists manipulates the elements of lists.

    + + +

    (Depending on context, I use both liftM and fmap.)

    + + +

    In your case, I’d use fmap (this choice is completely subjective, of course), to stress that I just want to change the contents of the monadic return value of (many1 digits):

    + + +
    fmap (Number . read) $ many1 digits
    + + +

    Also, some prefer to write this using infix notation:

    + + +
    Number . read `fmap` many1 digits
    + + +

    This way you see that fmap can be tought of being ($), only modulo monadic stuff.

    + + +

    BTW, fmap is useful on many other data structures, too:

    + + +
    fmap f (Just x) = Just (f x)
    +fmap f Nothing  = Nothing
    + + +
    fmap f (Left  x) = Left x
    +fmap f (Right x) = Right (f x)
    +-- You need Control.Monad.Error for this one.
    + + +
    fmap f xs = map f xs
    +-- With xs :: [a]
    + + +

    Happy Haskelling!

    +
    +
  6. + +
+
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + diff --git a/wayback/@done/sjs Typo and I are friends again.html b/wayback/@done/sjs Typo and I are friends again.html new file mode 100644 index 0000000..dc5e0a5 --- /dev/null +++ b/wayback/@done/sjs Typo and I are friends again.html @@ -0,0 +1,597 @@ + + + + sjs: Typo and I are friends again + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + +
+

+ Typo and I are friends again + +

+
+ Posted by sjs +
+on Wednesday, May 02 +
+
+

I’ve been really frustrated with Typo recently. For some reason changing my last post would cause MySQL to timeout and I’d have to kill the rogue ruby process manually before any other changes to the DB would work, instead of hanging for a minute or two then timing out. Luckily I was able to disable the post using the command line client, the bug only manifested itself when issuing an UPDATE with all the fields present. Presumably the body was tripping things up because most other fields are simple booleans, numbers, or very short strings.

+ + +

Add to that the random HTTP 500 errors which were very noticeable while I was trying to fix that post and I was about to write my own blog or switch to WordPress.

+ + +

I don’t love WP so I decided to just upgrade Typo instead. I was using Typo 2.6, and the current stable version is 4.1. They skipped version 3 to preclude any confusion that may have ensued between Typo v3 and the CMS Typo3. So it really isn’t a big upgrade and it went perfectly. I checked out a new copy of the repo because I had some difficulty getting svn switch --relocate to work, configured the database settings and issued a rake db:migrate, copied my theme over and it all just worked. Bravo Typo team, that’s how an upgrade should work.

+ + +

No more random 500 errors, things seem faster (better caching perhaps), and that troublesome post is troublesome no more. I am happy with Typo again.

+ +
+ +
+ +
Comments
+

Leave a response

+
+
    + +
+
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + diff --git a/wayback/mephisto/sjs A triple-booting, schizophrenic MacBook.html b/wayback/mephisto/sjs A triple-booting, schizophrenic MacBook.html new file mode 100644 index 0000000..6247467 --- /dev/null +++ b/wayback/mephisto/sjs A triple-booting, schizophrenic MacBook.html @@ -0,0 +1,660 @@ + + + + sjs: A triple-booting, schizophrenic MacBook + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + +
+

+ A triple-booting, schizophrenic MacBook + + 0 + +

+
+ Posted by sjs +
+on Thursday, April 05 +
+
+ The steps are well documented so I won’t get into detail here but if you have a backup and can wipe your disk all you do is: +
    +
  • Install OS X to a single partition filling your disk (optionally use your existing OS X intall)
  • +
  • Install rEFIt (no need to reboot just yet)
  • +
  • Re-partition your disk into 3 partitions with diskutil resizeVolume, reboot and confirm it all works
  • +
  • Boot the Vista install DVD and install to disk0s4 aka Partition 4
  • +
  • Install Gentoo (or other distro) to disk0s3 aka /dev/sda3
  • +
+ + +

With MacPorts and Gentoo/MacOSX the Gentoo install is superfluous but I’ll spare 12G just to see Gentoo run on this fine machine. Setting up the hardware should be fun. Right now I’m compiling X, (package 77 of 94) and the Core Duo is crunching code very nicely with 2G to work with, without any swap. I fully intend to put off creating a swap file unless I have to. Needless to say I’ll be running fluxbox or Xfce, none of that Gnome or KDE stuff. If I ever need a swap file I will eat my keyboard.

+ + +

[edit: 25 minutes to compile X.org, not too shabby!]

+ + +

My initial experience with Vista is quite good. Sadly the same old registry hack is required to swap Caps lock and Control but I was just glad it worked. I really like the new Start menu and the eye-candy is fairly pleasant for the most part. Till now I’d only used RC2 on a machine incapable of running Aero Glass and it looked terrible. I switched to Windows Classic just like I do with XP. Not so with Aero at its finest though. Without thinking about the price Vista is a nice upgrade to Windows. But because of the price and uncertainty of running Aero Glass I still hesitate to urge non-geeks to upgrade.

+ + +

OS X is OS X. It’s my favourite desktop OS right now because of apps like LaunchBar/Quicksilver and TextMate, a generally excellent UI, good old *nix stability, zsh out of the box! When I need WireShark or the GIMP X11 is there waiting. Mac notebooks are great and tight integration with the hardware is a clear advantage for OS X.

+ + +

Oh yeah, I also have a Parallels VM for Windows 3.11. It boots in about second to the C:\> prompt and then another second to type win and Windows to start. Without TCP/IP there’s not much to do though (I’m not going to write a driver for Parallels’ ethernet adapter).

+ + +
    +
  1. +
      +
    • Dual head setups are more work than plugging in a 2nd monitor, which is too much work.
    • +
    • X requires a restart to enable or disable a 2nd display.
    • +
    • Overall clunkiness such as displaying the houndstooth background before the WM starts,
    • +
    • and/or going through a screwed up mode with a black & white scrambled screen for a seconds before getting to the houndstooth.
    • +
    + back up ↑ +
  2. +
+ +

Like I said the X.org boys are doing amazing work. Hopefully soon after the current eye-candy craze is over they’ll get to more important work that needs to be done.

+ + + +
+ +
+ +
Comments
+

Leave a response

+
+
    + +
+
+ +
+
+ Comment +

+
+ +

+

+
+ +

+

+
+ +

+

+
+ +

+
+ +
+
+
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + diff --git a/wayback/mephisto/sjs Funny how code can be beautiful.html b/wayback/mephisto/sjs Funny how code can be beautiful.html new file mode 100644 index 0000000..5a75293 --- /dev/null +++ b/wayback/mephisto/sjs Funny how code can be beautiful.html @@ -0,0 +1,645 @@ + + + + sjs: Funny how code can be beautiful + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + +
+

+ Funny how code can be beautiful + + 0 + +

+
+ Posted by sjs +
+on Monday, April 30 +
+
+

While reading a Haskell tutorial I came across the following code for defining the Fibonacci numbers:

+ + +
fib = 1 : 1 : [ a + b | (a, b) <- zip fib (tail fib) ]
+ +

After reading it a few times and understanding how it works I couldn’t help but think how beautiful it is. I don’t mean that it’s aesthetically pleasing to me; the beautiful part is the meaning and simplicity. Lazy evaluation is sweet.

+ + +

Haskell is the most challenging real language I have tried to wrap my head around. I haven’t done much with any functional languages yet but they are truly fascinating. I’m beginning to understand monads1 but I’m quite sure I don’t see the whole picture yet.

+ + +

Erlang looks like it may be more suited to real world apps so I would like to learn that some time. The pragmatic guys have a book on Erlang in the works, and I love every book of theirs which I have read.

+ + +

Going deeper down the functional rabbit-hole you’ll find things like this polyglot quine, which absolutely blows my mind. I used to be impressed by the JAPH sigs or some of the various obfuscated contest winners but that first one definitely cleans the rest up with a perfect 10 in geekiness.

+ + +

[1] The following links have all been helpful while trying to wrap my head around monads.

+ + + + +
+ +
+ +
Comments
+

Leave a response

+
+
    + +
+
+ +
+
+ Comment +

+
+ +

+

+
+ +

+

+
+ +

+

+
+ +

+
+ +
+
+
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + diff --git a/wayback/mephisto/sjs Getting to know Vista.html b/wayback/mephisto/sjs Getting to know Vista.html new file mode 100644 index 0000000..08cdc07 --- /dev/null +++ b/wayback/mephisto/sjs Getting to know Vista.html @@ -0,0 +1,700 @@ + + + + sjs: Getting to know Vista + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + +
+

+ Getting to know Vista + + 0 + +

+
+ Posted by sjs +
+on Monday, April 16 +
+
+

It looks pretty good!

+ + +

After figuring out how to minimise the translucency of the window decorations I think Aero looks ok. Window titles, on both windows and the taskbar, can be difficult to read at a glance which is really stupid if you ask me. But it’s better than Luna! They really lay the effects on thick but overall I find it pretty pleasant and it runs well on my MacBook’s Intel 945 video chip.

+ + +

Ah yes, the Sidebar is nowhere to be seen on my desktop. It’s a nice-looking waste of space.

+ + +

But it’s not all useful

+ + +

Sadly The new task switcher (Win-tab) is terrible. Before using it I wondered why they didn’t replace Alt-tab completely. Now I know and I am grateful to MS for not replacing it. Alt-tab easily wins. Especially since it displays thumbnails of windows.

+ + +Three gripes with Win-tab fancy-shmanciness: +
    +
  • It’s too slow
  • +
  • It responds even when I just tap Win-tab to quickly switch, then I’m stuck until I hit the Windows key to choose a window
  • +
  • Windows from all my monitors are gathered onto the main one, which is just lame
  • +
+ + +

It’s stable (so far)

+ + +

Besides the fact it is aesthetically pleasing [subjective] it also has just worked for me so far. Nothing has crashed or broken which is almost miraculous. Not that I had a terrible time with XP, but it was still frail old Windows at times. I’m equally pleased with Apple’s drivers for Windows which probably adds to the experience. I’ve used XP machines with proper drivers, and those without and the differenc is night & day. I’ve had uptimes in months on a stable XP notebook.

+ + +

Never thought this day would come…

+ + +

But I actually like the Start menu. Really, I do. You hit the Windows key, type a few letters and boom you launch your app or search your computer, or the web (Google in Firefox, my default search). It’s not QuickSilver or LaunchBar; it’s not supposed to be. For the average Joe this is cool, and for the average power user it’s very useful. For the casual Windows user it’s great. It even learns.

+ + +

I don’t love it though. I knew before using it that the new method of navigating through the All Programs menu would be weird. It is, but I guess it may be better than the previous fly-out scheme (which I don’t care for either). I guess the All Programs menu is more or less legacy now though and I don’t see myself using it often.

+ + +

I’m a command line junkie

+ + +

They fixed at least one glaring bug. I used the cmd.exe shell a little bit even though I hate it. I was happy to find that Tab completion works for more than the current directory now. Before Vista it would complete the same entries from PWD no matter how deep you tried to drill down into the filesystem. Other than that it seems to be the same crummy shell. [edit—apparently this is fixed in XP as well, my mistake]

+ + +

I installed the Windows PowerShell (PoSH) but haven’t really put an effort to learn it yet. The syntax is unorthodox coming from *nix shells (zsh), but it’s sort of refreshing and it lives up to the Power part of its name. I really like the fact that collections of (say) files can be passed around and iterated over, filtered, etc. not as filenames but as real objects with corresponding methods and metadata. Built-in support for XML is pretty nifty too.

+ + +

I’ve often longed for a shell which acted like a normal shell for the most part, but allowed irb-like interpretation of arbitrary Ruby code as well. The PowerShell seems like it could be something similar to what I’ve wanted. Too bad it’s proprietary and only runs on Windows. If I use Vista a lot this summer I could end up getting into it more though. It’s quite interesting.

+ + +

Random

+ + +The good: +
    +
  • Slideshow button in Explorer
  • +
  • Doesn’t look like a Fisher-Price design
  • +
  • Restarts when I click Restart (after 3 clicks it damn well better)
  • +
  • Seems stable, at least initially which means the installation & driver situation really has improved
  • +
  • I don’t want to kill anyone while using it
  • +
+ + +The bad: +
    +
  • Flicker while changing video modes, displaying UAC prompts, etc. (not so bad really, but stands out on an otherwise smooth desktop)
  • +
  • Long black screen on boot after installing updates
  • +
  • Disappearing / magical menu bar debacle
  • +
  • The shell still sucks
  • +
  • It tries to be too fancy, with the dynamic Start menu icon and the like
  • +
+ + +

My conclusion

+ + +

Perhaps the scores of talented developers at Microsoft can save them despite their obvious shortcomings in management. .NET seems like a decent platform, but we’ll have to see how I like it once I actually use it. So far I don’t hate Vista and considering the previous versions of Windows that’s a pretty good review coming from me. I’m still recommending Macs to my family and friends, but who knows what the future holds. I don’t hate Vista and by the end of the summer I may even [gasp] like it, and/or .NET. I haven’t used an IDE since VB6 and MS has always had a decent IDE (albeit with a crummy text editor). I’m expecting to enjoy it. If there’s one thing MS knows it’s the value of good dev tools and developers.

+ + + +
+ +
+ +
Comments
+

Leave a response

+
+
    + +
+
+ +
+
+ Comment +

+
+ +

+

+
+ +

+

+
+ +

+

+
+ +

+
+ +
+
+
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + diff --git a/wayback/mephisto/sjs Quickly inserting millions of rows with MySQL InnoDB.html b/wayback/mephisto/sjs Quickly inserting millions of rows with MySQL InnoDB.html new file mode 100644 index 0000000..0e91486 --- /dev/null +++ b/wayback/mephisto/sjs Quickly inserting millions of rows with MySQL InnoDB.html @@ -0,0 +1,690 @@ + + + + sjs: Quickly inserting millions of rows with MySQL/InnoDB + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+ + + + +
+

+ Quickly inserting millions of rows with MySQL/InnoDB + + 0 + +

+
+ Posted by sjs +
+on Thursday, April 26 +
+
+

The absolute first thing you should do is check your MySQL configuration to make sure it’s sane for the system you’re using. I kept getting a ‘The table is too large’ error on my Gentoo box after inserting several million rows because the default config limits the InnoDB tablespace size to 128M. It was also tuned for a box with as little as 64M of RAM. That’s cool for a small VPS or your old Pentium in the corner collecting dust. For a modern server, workstation, or even notebook with gigs of RAM you’ll likely want to make some changes.

+ + +

Tweaking my.cnf

+ + +

Here are the relevant settings you can tweak in order to work with large datasets efficiently. These are set in your my.cnf file, which varies in location.

+ + +

On Gentoo it resides at /etc/mysql/my.cnf.

+ + +

When MySQL 5.x is installed via DarwinPorts on Mac OS X you need to copy one of the defaults from /opt/local/share/mysql5/mysql/ to /opt/local/etc/mysql5/my.cnf and then modify it accordingly.

+ + +

If you use another system you’re on your own. If you can’t figure it out, please put down the text editor and leave the poor config file alone! Jokes aside this really is not difficult if you’re used to configuring *nix programs.

+ + +

innodb_buffer_pool_size

+ + +

This determines how much memory MySQL uses for table indexes and data. You can set it as low as 8-10M, or high as 50-80% of your memory on a dedicated MySQL server. I have RAM to burn1 in my workstation so I set this to 200M, 20% of my 1GB.

+ + +

[1] I run Fluxbox on Gentoo, I use 200-300M of my 1GB on average and with 200M for MySQL 409M are in use at this moment. Gotta love those lightweight window managers!

+ + +

innodb_additional_mem_pool_size

+ + +

According to a post1 on a MySQL mailing list, modern OSs have fast enough mallocs and this variable has little effect on performance. I set mine to 16M before reading that post, so I’ll just leave it at that.

+ + +

[1] http://lists.mysql.com/mysql/129247

+ + +

innodb_data_file_path

+ + +

On Gentoo this one bit me right in the ass, and I mentioned it above. It specifies how large the files used to store your data can be, and how many of them there are. The default setting is almost sane: ibdata1:10M:autoextend:max:128M. Limiting the total size to 128M caused my test to fail after inserting several million rows.

+ + +

Simply removing max:128M solves the problem. The resulting setting tells the InnoDB engine to use one file, named ibdata1 which is initially 10M in size and grows as required.

+ + +

innodb_log_file_size

+ + +

The default Gentoo config says they (whoever they are) keep this at 25% of innodb_buffer_pool_size so I did just that. 50M in my case.

+ + +

innodb_log_buffer_size

+ + +

Again I only went as far as the Gentoo config to learn about this setting. They had it at 8M and recommend increasing it if you have large transactions. I can’t think of any particularly large transactions I currently use but I doubled it to 16M anyway.

+ + +

Save my.cnf and restart mysqld

+ + +

That’s it for the MySQL config. Restart mysqld however you do that on your platform. sudo /etc/init.d/mysql restart should look familiar to many *nix users.

+ + +

Now you should be able to insert dozens and indeed hundreds of millions of rows into your InnoDB tables. Sadly this brought little performance gains to the table. MySQL wraps single queries in implicit transactions. Wrapping everything in a transaction may work, but inevitably something will go wrong and you may want the ability to resume inserting the rows instead of starting all over.

+ + +

The solution now is to execute SET AUTOCOMMIT=0 before inserting the data, and then issuing a COMMIT when you’re done. With all that in place I’m inserting 14,000,000 rows into both MyISAM and InnoDB tables in 30 minutes. MyISAM is still ~ 2 min faster, but as I said earlier this is adequate for now. Prior to all this it took several hours to insert 14,000,000 rows so I am happy.

+ + +

Now you can enjoy the speed MyISAM is known for with your InnoDB tables. Consider the data integrity a bonus! ;-)

+ + + +
+ +
+ +
Comments
+

Leave a response

+
+
    + +
+
+ +
+
+ Comment +

+
+ +

+

+
+ +

+

+
+ +

+

+
+ +

+
+ +
+
+
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + diff --git a/wayback/scrape-mephisto.js b/wayback/scrape-mephisto.js index 8b646ed..8c28819 100755 --- a/wayback/scrape-mephisto.js +++ b/wayback/scrape-mephisto.js @@ -48,9 +48,9 @@ function onLoad(err, window) { , post.body , '' ].join('\n') - , slug = strftime('%Y-%m-%d_' + post.title + , slug = strftime('%Y.%m.%d-' + post.title .toLowerCase() - .replace(/[^\sa-z0-9_-]/g, '') + .replace(/[^\sa-z0-9._-]/g, '') .replace(/\s+/g, '-'), new Date(post.ISODate)) console.log('slug: ' + slug) fs.writeFileSync('../recovered/' + slug + '.html', s, 'utf8') diff --git a/wayback/scrape-typo.js b/wayback/scrape-typo.js index 2f6636b..258dcf8 100755 --- a/wayback/scrape-typo.js +++ b/wayback/scrape-typo.js @@ -48,9 +48,9 @@ function onLoad(err, window) { , '' ].join('\n') - var slug = strftime('%Y-%m-%d_' + post.title + var slug = strftime('%Y.%m.%d-' + post.title .toLowerCase() - .replace(/[^\sa-z0-9_-]/g, '') + .replace(/[^\sa-z0-9._-]/g, '') .replace(/\s+/g, '-'), new Date(post.ISODate)) fs.writeFileSync('../recovered/' + slug + '.html', s, 'utf8')