Sunday, March 30, 2008

Amazon's Music Store on Ubuntu Gutsy

Unfortunately, there are some CDs that are so obscure nobody is seeding them on BitTorrent. One of these happens to be Hicksville by Celtic Cross. I decided to give the Amazon Music Store, where this CD is available for purchase, a shot.

On Ubuntu Gutsy, there are a few things you need to do to make this work. The first, of course, is to download the .deb package from this page. Install that with sudo dpkg -i amazonmp3.deb or sudo dpkg --force-architecture -i amazonmp3.deb if on a 64 bit system. You're also going to need a few Boost libraries: sudo apt-get install libboost-date-time1.34.1 libboost-thread1.34.1 libboost-iostreams1.34.1 libboost-signals1.34.1 If you're on a 32 bit system, launching the /usr/bin/amazonmp3 binary should now work (it also inserts an entry in the GNOME panel under Applications->Internet).

But for all you 64-bit'ers out there, there's a bit more work to do. Launching the binary fails with the message "amazonmp3: error while loading shared libraries: libgtkmm-2.4.so.1: cannot open shared object file: No such file or directory". This is because amazonmp3 needs 32 bit libraries, not 64 bit ones (see this thread). Download getlibs, a bash script which installs 32 bit versions of libraries on 64 bit systems. Install the package with sudo dpkg -i getlibs-all.deb and then run getlibs /usr/bin/amazonmp3 to install the 32 bit libraries. The program should now run without error.

The application, by the way, is quite minimalistic. I don't know why they put users through this trouble and don't just send you a tarball of the music files. I guess there might be some reason on other platforms where it integrates with other applications... not on Linux, though!

Wednesday, March 12, 2008

Why NIN's "Ghosts" Release Matters

Nine Inch Nails ushered in another landmark event in the slow march towards freedom of digital media recently when it released its newest work for free (gratis and libre) on its web site. NIN band member Trent Reznor has frequently been at the forefront of innovation in music and the surrounding areas and it is not at all surprising and very pleasing that it is him to be the first high-profile artist (to my knowledge) to release a major work under a Creative Commons license. However, not everyone seems to grasp the significance of what has happened here. In fact, not even the article that the Slashdot article links to reports the fact that the album has been released under a CC license and many other news outlets have neglected this important point as well. In this article, I'll give a summary of the events surrounding NIN's release of Ghosts I-IV and an analysis of its significance.

First, some history of the band: Nine Inch Nails has never been a conformist where promoting its music has been concerned. The history of their original ideas is impressive: breaking off from their label and releasing their work independently; encouraging fans at concerts to "steal" music; hiding USB drives for fans to find with new, unreleased songs on them; performing surprise concerts as part of an elaborate fantasy world constructed for fans and releasing Garageband samples for others to remix.

There is precedent for releasing music free (both gratis and libre) online. Most artists now have a myspace page or other limited Internet presence where one can listen to, but usually not download (or only download a small piece of) an album. Many low-profile artists have been releasing their music online for years under various licenses. Radiohead, arguably, has been the most famous band to release an album free of charge online (with In Rainbows last year). Radiohead allowed each customer to specify their own price for a full download of the album off of its site, even $0. It is estimated that Radiohead made many millions of dollars with this tactic.

Next, the facts about the Ghosts release. From the Nine Inch Nails website there are a variety of options for downloading the album, etc:
  • Free: The first 9 tracks from the Ghosts I-IV collection available as high-quality, DRM-free MP3s, including the complete PDF.
  • $5: All 36 tracks in a variety of digital formats including a 40 page PDF.
  • $10: Ghosts I-IV on two audio CDs in a six panel digipak package with a 16 page booklet. Pre-order, to be shipped April 8, 2008. INCLUDES immediate full download in a variety of digital formats.
  • $75: Ghosts I-IV in a hardcover fabric slipcase containing: 2 audio CDs, 1 data DVD with all 36 tracks in multi-track format, and a Blu-ray disc with Ghosts I-IV in high-definition 96/24 stereo and accompanying slideshow.
  • $300:



Nine Inch Nails also uploaded a torrent to the Pirate Bay of the first 9 tracks of the album (out of 36 total) with the following message:
Hello from Nine Inch Nails.

We\\\'re very proud to present a new collection of instrumental music, Ghosts I-IV. Almost two hours of music recorded over an intense ten week period last fall, Ghosts I-IV sprawls Nine Inch Nails across a variety of new terrain.

Now that we\\\'re no longer constrained by a record label, we\\\'ve decided to personally upload Ghosts I, the first of the four volumes, to various torrent sites, because we believe BitTorrent is a revolutionary digital distribution method, and we believe in finding ways to utilize new technologies instead of fighting them.

We encourage you to share the music of Ghosts I with your friends, post it on your website, play it on your podcast, use it for video projects, etc. It\\\'s licensed for all non-commercial use under Creative Commons.

We\\\'ve also made a 40 page PDF book to accompany the album. If you\\\'d like to download it for free, visit http://ghosts.nin.com/main/pdf

Ghosts I is the first part of the 36 track collection Ghosts I-IV. Undoubtedly you\\\'ll be able to find the complete collection on the same torrent network you found this file, but if you\\\'re interested in the release, we encourage you to check it out at ghosts.nin.com, where the complete Ghosts I-IV is available directly from us in a variety of DRM-free digital formats, including FLAC lossless, for only $5. You can also order it on CD, or as a deluxe package with multitrack audio files, high definition audio on Blu-ray disc, and a large hard-bound book.

We genuinely appreciate your support, and hope you enjoy the new music. Thanks for listening.

http://ghosts.nin.com
A little while after the release of the album and the spreading of the news, the NIN website got overloaded with requests, prompting Trent Reznor to post the following message there:
Update: The response to this album has been overwhelming, causing our website to slow to a crawl. We THOUGHT we were ready, but...
We've been adding more servers to accommodate the unexpected demand and we expect to be running smoothly in the next few hours. In the meantime, if you've had any problems with downloads from the Ghosts site, don't worry - you'll be able to use your download link again when the site is more stable. Thanks everyone for making this such an immediate success.

posted by Trent Reznor at 5:47 PM pst, from hong kong.
So why is the release of Ghosts significant? Because it's the most visible release of art under a Creative Commons license to date (by-nc-sa 3.0, to be exact). This means that Trent Reznor can not take you to court for distributing the music on, say, the Pirate Bay; it explicitly permits this kind of activity. All the license mandates is that if you use the work, you must credit the original author and you must release your new work that incorporates NIN's art under the same license. The license also prohibits any use of the work for financial gain by a third party (no selling the album on the street for five bucks a pop). This is in marked contrast to Radiohead, who did not specify the license that In Rainbows was under, so because of this ambiguity we must only assume that it is under a traditional copyright license. This means that Radiohead CAN take you to court for distributing the music if one day it decides that suing its fans is fashionable. Releasing art, especially music, in this fashion is going to become increasingly prevalent as more artists realize the benefits of instantly sharing art with the world via the Internet in preference to traditional distribution channels such as record labels. With computer technology, how fans use music is increasingly out of an artists' control. It is a much more amicable arrangement for the artist to indulge fans by releasing music in a way they find convenient (and, also, not sue them).

The release of Ghosts also establishes BitTorrent as a recognized distribution channel in which established artists can release their music. Frequently, the BitTorrent protocol and its users are denigrated in the media as "pirates" or "thieves." The fact that a respected artist is using BitTorrent in preference to direct download or a record label-sponsored distribution will legitimize this method of sharing in the eyes of many and heighten the profile of BitTorrent generally. Using BitTorrent was also a good move simply because it is a superior protocol for large files, as the slowness of the NIN website showed. Also, it is more convenient to use than having to click through the kind of omg-it's-free messages (or, more generally, an unfamiliar interface) that Radiohead made users weather to buy In Rainbows. Being so in touch with how music fans want to acquire their music definitely doesn't hurt NIN's publicity, either.

Reznor also proves that it is wholly possible to make a lot of money off of a free product on the Internet, something that many ill-informed pundits think impossible. Slashdot reports that the most expensive option sold out in about a day, netting Reznor $750,000. This is to say nothing of any of the other purchasing options, which also likely brought in a significant amount of revenue, possibly much more than the $300 dollar option. So why are people paying for something that they could more or less otherwise get for free? A few answers can be found in Kevin Kelly's essay Better Than Free. Kelly claims that the Internet has made copyable material infinitely abundant, and therefore impossible to charge money for. What can be charged for are what Kelly calls "generatives" -- things that can't be copied. He suggests 8 generatives from which money can be made in a world with Internet technology: immediacy, personalization, interpretation, authenticity, accessibility, embodiment, patronage and findability (convinience). By autographing records, NIN provides authenticity and personalization. By offering downloads off its site in a variety of digital formats, NIN makes money off of findability, accessibility and immediacy. And, of course, being an artist offering up works for free under a CC license NIN reaps the benefit of patronage: listeners loving what they are seeing and hearing and willing to pay for more of the same.

Another important point about this event is that all the data on NIN's site will eventually find its way out from behind the wall of authentication and payment and onto public networks. That is, users that paid for enhanced versions of the product will upload them to a BitTorrent tracker: here already are the ($5) FLAC versions of all 36 songs and some extras. It is often repeated that information wants to be free, as we can see here. What is not often repeated, but equally true, is that information wants to be convenient. Fans of In Rainbows proved this yet again when they uploaded the album to BitTorrent (humorously leading some ignorant columnists to castigate users for "stealing" it -- how can you steal something if it's free and able to be infinitely copied?).

In conclusion, the experimental release of Ghosts on the Internet under a Creative Commons license and for free is a milestone event for a variety of reasons. It is the first high-profile musical release that is free, both as in freedom and as in beer. It made NIN a whole lot of money, proving that artists can survive in the Internet era (even without performing). And it enhances the profile of the BitTorrent protocol as a distribution mechanism and reinforces some well-understood properties of Internet-based information distribution. Hopefully other artists will follow NIN's example and release their work in a similar manner.

===============================
Further reading:
  • Reznor decries fact that people see Radiohead as first to release free online, says industry won't follow his lead anytime soon because it's inept. (Link)

Thursday, February 21, 2008

Ruby (vs Python): a preliminary assessment

I've been using Ruby for a little over a month now. While this hasn't been enough time to explore the depths of the language, it has given me ample time to evaluate how I feel about some of the more superficial aspects of Ruby. There are some things I like about it, a few things I don't care about, and a lot of things I don't like. In some aspects it is quite similar to Python, my favorite programming language. In the following sections I lay out what I do, kinda, and don't like about Ruby, sometimes in comparison to or in contrast with Python to put things in context.

Things I like about Ruby


Naming conventions are enforced The less surprises there are in code, the easier it is to read. I would be very surprised, for example, if a C VARIABLE_IN_ALL_CAPS were not a constant. It only takes one joker working on code to completely screw with convention and degrade readability of code for everyone else working on it. Ruby heads off this problem at the pass. Instance variables look like @this, class variables look like @@this, constants look like THIS, global variables look like $this, etc. This is a Good Idea. I can easily live without the flexibility to name my class h0We\/ER_I_want. This also makes the code easier to parse and syntax highlight.

Block Comments I'm not sure how Python missed the boat on this one. The "large chunks of code shouldn't be commented anyway, so take them out" and "get a decent text editor that can :50,70s/^/#/" and "that's what doc comments are for" school of thought just doesn't resonate with me. Too often there is some large chunk of code lying around that just isn't applicable anymore and quickly commenting it out is a temporary solution.

Constants There is just something about the assurance that certain variables are read-only that makes me sleep well at night. Otherwise, I need to worry about things getting overwritten, and that's no fun. I guess there's always CONVENTION to prevent this in Python, but that doesn't stop someone from breaking CONVENTION += 1

Examples are the norm in documentation Examples are the quickest way to learn about new code. However, the docs could benefit from some non-example elaboration most of the time. How is one supposed to figure out corner cases? I guess "examples first" goes along with the whole Ruby-has-no-formal-spec thing.

'case' syntax The syntax of Ruby's case statement (analogous to switch in other languages) is pretty rad. It's a great feature for when multiple properties of one variable need to be tested. The case statement accepts comparisons, ranges, regular expressions, etc. Very cool.

Things I could go either way on

Regular expressions built into the language Regular expressions are cool, and I use them a lot, but I just don't know if they have a place amongst the pantheon of hashes, lists and the like. They are convenient, but overuse might turn your code into *gasp* Perl. No one likes unreadable ASCII-splatter, although it's tough for Ruby to get that bad. Plus, half the time I am using regexes some other function might do just as well, like rindex. Maybe that's just my laziness that Ruby caters to.

Interned strings It's like a pointer, I get it. It saves memory over using a string object, cool. Was it really worth including in the language? Not sure. It seems like their most common uses, such as keys in hashes, could be implemented under the hood anyway (well, at least in a real language like Python where hash keys are immutable).

! and ? as legal characters in method names I can understand that does_this_work? is a natural way to read that a function returns a boolean. I get that destroy! suggests an internal change of state of the object. But then there's the problems. First, not every method that returns a boolean or changes an object's state is forced to use these constructs. If they were enforced like all-caps constants and @ before instance members, maybe I'd be more bullish on them. Second, what qualifies as a change of state can get kind of messy: maybe a method only conditionally changes its object's state; is an exclamation mark appropriate then? The exclamation mark can also be misread, especially if parentheses are omitted (looks an awful lot like a logical not operator, doesn't it?). And now for my nitpicky objections: ? and ! are harder to type than letters and vim doesn't auto-complete the full method name by default (it completes everything but the last character) if one of those characters is included.

Marriage to Rails On the one hand, it's nice to have a large support community for tools that one is likely to use. On the other hand, it's annoying to wade through a bunch of comments by people on forums and mailing lists that are completely irrelevant to what you're trying to do with the language. These people are normally exclusively concerned with getting their website up and running, aren't terribly gifted programmers and don't really care about the language per se. Some bloggers assume that any talk about Ruby is in the context of Rails because... well, isn't that what you're using it for? What else could you possibly do with Ruby?

Indentation Python has a unique indentation system. In most cases (Makefiles) whitespace indentation is a horrible idea, but Python manages to make it work. It reduces noise on the screen and is pretty intuitive. I'm not convinced that Python wouldn't be more effective, however, with a traditional bracket-defined indentation scheme which Ruby is close to. It's a toss-up for me.

Things I don't like about Ruby


TMTOWTDI There's more than one way to do it in Ruby, alright -- you're smothered with options. This is the dark path that leads to Perl. Take looping as an example. In Python, you have for and while. That's it. In Ruby, you have for, while, times, upto, downto, begin/end and each (there's probably more that I missed). What's wrong with for? It's really difficult to be intimately familiar with this many options. And this symptom doesn't just plague looping, it also plagues the standard library. Do we really need every one of <<, push and + to append to the end of an array? Why have both brackets and "end" to enclose a block? Has anyone ever used all three versions of defining a class method in any mood but malice and spite? I guess we can all take solace in the many ways in Ruby via active_support to compute the amount of bytes in a gigabyte: 1.gigabyte, 1024.megabytes, 1048576.kilobytes, etc.

Go with the Flow There is a prevailing attitude with Ruby users, especially in Rails, to favor convention over configuration. This means that tools that espouse this philosophy reward going with the flow and punish breaking out of the mold and customizing your applications. My attitude towards this philosophy is this: unless you are creating the most pedestrian and generic of applications, you are going to need to customize the application at some point. When that happens, it is much better to have a tool that allows flexibility than one that disdains it. Otherwise you are going to need to go down to the core of the tool to make minor changes to your application, and that will cost you in time and sanity.

Hashes are broken In Python, it's impossible to change the keys in a dictionary because those keys must be immutable when they go in. Python also nicely throws a KeyError when something you're looking for in a dictionary is not there. Ruby does neither of these things; the programmer is expected to maintain the immutability of hash keys. High-level languages are supposed to take care of important details like these for us humans who are busy thinking about other things. In fact, the Python FAQ lists this as an "unacceptable solution" for an alternative implementation of hashes: "Allow lists as keys but tell the user not to modify them. This would allow a class of hard-to-track bugs in programs when you forgot or modified a list by accident." Default return values aren't that much of a design travesty, but I still prefer the error. Besides, if you really want a default return value in python, you can just use setdefault when accessing the element that may or may not be there instead of setting a default value for the whole hash at creation.

Ranges are broken This absolutely baffles me. Why did Ruby not choose to incorporate Python's elegant slicing syntax and instead chose a less powerful and more confusing one? Why did Ruby choose to create an unnecessary class called Range when they just could have had a function called, oh I don't know, range that is much more powerful, simple and general and that returns lists/arrays? Why do you need to call range.to_a to convert your useless Range object to an array in Ruby when they could have just used a function like range and gotten to the point? Furthermore, why are there two ways to create ranges, .. (two periods) and ... (three periods) that look EXACTLY THE SAME! Argh.

Optional omission of syntax elements Sure, it's less typing in Ruby, but remember what I said earlier about less surprises equaling more readable code? It holds here as well. Is this_thing a variable or a function call? This also excludes the convenient syntax for introspection that calling function() without parentheses in Python affords. And the fact that sometimes you need the "do" keyword and sometimes you don't is also a design decision that just begs for unnecessary tripping over the syntax.

Inline control flow constructs When I first saw these, I thought "Wow! I can now do in one line what previously took me three in Ruby!" And then I started reading a lot of lines and wondering why they weren't executing. And then I read those lines a bit further and saw that they had conditional statements tacked on to the end of them. And then I vowed to never use them again. One example of how this can go bad is tacking on "and return" to the end of a long statement. If you're looking at the code, and not scrolling right far enough (and your lines are that long that you need to scroll, which may or may not be a good idea), it looks like the code falls through after every statement instead of returning. Confusing.

Different names for the same method find_all? What the hell does that do? Oh, it's the same as select. Collect? What's that? Oh, it's the same as map. Too bad I only found these things out after going to the documentation. Why can't one function just have one name, so we can all have a common point of reference? Oh, right, because Ruby "allows you to program in your natural language." Which means confusing everybody else, including myself.

Different precedence for seemingly identical operators ! binds more tightly than not. && and || bind more tightly than "and" and "or". This is incredibly confusing; why not just make them the same precedence? Changing one form to the other form when it is right near another operator whose precedence is between the two could alter the control flow of your code.

Inability to override = (and non-obvious performance gotcha) There is some fine print to go along with the "every operator is just a function" propaganda. One annoying exception to the rule is the = operator. Now, why would anyone want to override the equals sign? First let me point out that it's not just =, but also -=, +=, *=, etc. that also are incapable of being overridden, so it affects a substantial set of important operators that are literally expanded to x = x + y, etc. Now here's the kicker: these methods are orders of magnitude slower than their true method counterparts for arrays and strings. So I want to override += for arrays to have it call concat or << which are both efficient as a way of aliasing all +='s in the existing codebase. In C++ and other languages, this would be quite possible (never mind that you wouldn't be facing this problem in C++ to being with) but in C Ruby, a design decision has been made that no one can override the sacred = and therefore coders will inevitably trip over this performance gotcha. Why? I'm not sure... maybe this or that post may offer some insight. In any event, don't use += and its cousins for anything but numbers or risk serious performance hits (changing one to the other is further complicated by their difference in precedence... both behave differently within a conditional operator, for example. Grrr.)

Confusing operator overloading << is a way to print things out (a la C++), define a class method, and append to the end of an array. Only the last one makes sense to me; the other two seem out of place. Remember what I said about less surprises = better code readability? It's beginning to become quite a theme...

No list comprehensions [heavy_sigh for each_time_I_can_not_do_this in Ruby if I_am_particularly_exasperated] I guess there's always select and collect. Too bad I need to decide if I want all the items in the list or only a subset before I can select the correct method to use (instead of at the end in Python, where I can insert if statements if necessary). I also haven't discovered a way in Ruby (yet?) to do the related task of a one-line instantiation of a hash. In Python, this would be d = dict((x, None) for x in [1,2,3])

Perl-like operators << <=> and =~? Sorry, I just can't get into it. Keep it simple, please. Function calls with letters are good.

Lists and hashes are printed strangely puts {1=>2,2=>3,3=>4} gives me 122334 in Ruby. WTF? I thought I was dealing with a hash, not a number. print {1: 2, 2: 3, 3: 4} gives me {1: 2, 2: 3, 3: 4} in Python. puts [1,2,3] gives me numbers on separate lines in Ruby. print [1,2,3] gives me [1, 2, 3] in Python. The seemingly small detail that data structures are printed out exactly how they are written in code makes a world of a difference.

Strings are unintuitive Strings are iterated over by word, not by character in Ruby: "one two".each {|x| puts x} in Ruby outputs "one" and "two" on separate lines. Compare this to for i in "one two": print i in Python, which prints out a character on each line. To iterate over each character in a string in Ruby, you'll have to use each_byte (in which case you'll find that Ruby will print out numbers unless you convert the numbers with .chr... this problem also occurs when selecting a character from a string, as in str[5] even though the docs say otherwise) or each_char.

Bad decisions on naming Why is there a built in variable called $DEBUG? Doesn't everyone have a global variable called that in their program at some point or another? Well, overwriting this variable unknowingly will cause your code do very strange things, like disregard begin/rescue/ensure blocks. I found this out the hard way. Python's is __debug__. Who is going to create a variable called __debug__ in their program? Nobody, that's who. The closest thing Ruby has to a constructor is called initialize. Why so long? __init__ works fine, and programmers who failed literature can actually spell it.

Shortcuts for everything "p" for print. The attr family of keywords for attribute access. Why not just create usable constructs and stick with them, instead of inventing unwieldy constructs and then working around them with shortcuts?

Hype Ruby is definitely the flavor of the week in programming languages. This results in a bunch of n00bs flocking to the language when they want to learn to program. Now, I have nothing against people who want to learn how to program. In fact, I'm thrilled that anyone wants to take a little time to learn the art. But the experience of a community has benefits: better tools and better discussions. As a result the conversations in Ruby forums and mailing lists are generally of a lower quality than that on Python mailing lists which tend to be frequented by more knowledgeable, veteran coders.

Japanese Origins As an English speaker, I appreciate that most of the cutting-edge blog posts and PEPs and what not are in English. Ruby originated from Japan, so this is not the case there. It's frustrating for me to see a link like "the solution to your problem is here" only to be led to a page which to me might as well be in... well, Japanese. I am sure I would feel differently if I were Japanese, of course.

OSX/TextMate-centric community A large number of Ruby users use Macs. Not sure why, that's just the way it is. They also seem to like TextMate. Me? I hate Apple and love vim. The more people that use the tools that you use, the higher probability that someone has already solved the configuration problem that is bugging you. Although I will note that the default settings for Ruby in vim are very nice... there's at least one knowledgeable vim user writing Ruby out there.

Younger Language Python has been around since the late 80s. Ruby has been around since 1993 (both for certain definitions of "around"). Python has a head start on Ruby in terms of developer time. A more mature language is likely to have fewer bugs, more features, less experimentation and and more users. The same goes for libraries written for that language: a greater number of better-implemented libraries will be available to users of a language that has been around longer. All other things being equal, the older language has to win the stability and reliability battle.

Unfamiliar keywords Instead of try/catch (or except)/finally, Ruby has begin/rescue/ensure. Instead of continue, Ruby has next. Instead of else if or elif, Ruby has elsif. Instead of switch/case, Ruby has case/when. I guess every language commits this foul to some extent, but it's just one more thing to trip over.

Implicit returns Another Perlism that I despise. To me, a function looks like it doesn't return anything if it doesn't have the "return" keyword in there at some point. It's much easier to read (and maintain) code if the points at which a function could return something are explicitly outlined.

Things I don't have an opinion on... yet

Introspection/Reflection Haven't really dug that deeply into what Ruby can do here yet...

Package management The gems system vs letting apt-get do everything. Neither has failed me in any way thus far, but then again, I haven't really tried to do anything remotely complicated with either and I'm not a sysadmin presiding over a myriad of different configurations...

Threading Ruby doesn't support native threads. What are Python's options? This looks like a good article and what about Stackless Python?

Object Oriented stuff Namespaces, modules, Inheritance, etc. I'm sure there's some Python vs Ruby flamewar going on out there, I just have to find the thread...

Monday, January 07, 2008

Funny UNIX utilities

Some humorous UNIX utilities that brighten my day:
  • cowsay -- get a cow, etc. to do the talking
  • fortune -- witticisms, some more offensive than others (fortunes-off package contains more offensive fortunes, fortune -o invokes offensive fortunes)
  • banner -- big friggin letters

Printing with enscript

enscript is an awesome utility for printing text files; it kicks lpr's lame ass. Here are some examples of usage (more to come as the need arises):
  • Letter enscript --no-header --word-wrap example_file.txt
Also, navigate to localhost:631 on any system with CUPS installed in order to configure the default printer and such.

Friday, December 14, 2007

Learning Ruby from Python

I just started to pick up Ruby today (to install: sudo apt-get install ruby irb ri rubygems). Here are some things I learned along the way, coming from a Python mindset. The (very good and highly recommendable) references I looked at were (in order):
  1. Ruby in Twenty Minutes
  2. To Ruby From Python
  3. Ruby Essentials (free, on-line book)
  4. Important Language Features and Some Gotchas
Similarities
  • Brackets for arrays, braces for dictionaries (called hashes in Ruby)
  • Strong dynamic typing
  • Everything is an object, variables are just references
  • Exceptions are similar
  • No special line termination characters
  • # for single line comments
  • def to define a method, class to define a class
Differences
  • Interactive prompt: python => irb
  • Interactive prompt help: help(str.count) => help "String#count"
  • Interactive prompt reload: reload(foo) => load "foo.rb"
  • Command line docs: pydoc => ri
  • File extension: .py => .rb
  • Shebang line: #!/usr/bin/python => #!/usr/bin/env ruby
  • Indentation and blocks: : and tabs => either { } or end
  • Strings: immutable => mutable (can use freeze method for immutability)
  • Naming conventions: unenforced => enforced (ex. class names start with a capital letter, variables start with a lowercase letter)
  • Raw strings: r"blah" => 'blah'
  • Parantheses: mandatory => sometimes optional
  • Booleans: True, False => true, false
  • Null value: None => nil
  • Else-if statement: elif => elsif
  • Module import: import foo => require "foo"
  • Boolean conversion: 0, False, None and anything empty => Only nil and false
  • Doc generation: docstrings below things => regular comments above things
  • Output: print => puts (or print if you don't want a trailing newline)
  • Command line execution: python -c => ruby -e
  • Global Variables
  • Ranges: range(x,y) => x...y exclusive, x..y inclusive (.to_a to return array)
  • Slicing: arr[1:3] => arr[1...3] or arr[1..2] (inclusive)
  • Object initialization: __init__ => initialize
  • Object creation: a() => a.new
  • Ternary operator: if_true if statement else if_false => statement ? if_true : if_false
  • Substring matching: 'foo' in str => str['foo']
  • "Main": if __name__ == '__main__' => if __FILE__ == $0 ... end
Philosophical differences
  • Attribute access: direct access => method calls
    • Need getter and setter methods to access attribute outside class
  • Access permissions: convention by underscore => public, protected, private
  • Multiple inheritance: allowed => mixins
Stuff Ruby has that Python doesn't
  • Double quoted strings allow expression substitution #{} and escape sequences \t\n
  • You can re-open a class at any time and add more methods
  • Block comments: ==begin and ==end
  • Special variable characters (begins with...):
    • $ global
    • @ instance
    • [a-z_] local
    • [A-Z] constant (triggers warnings when reassigned)
    • @@ class
  • Arrays support some set operations
    • difference -
    • intersection &
    • union |
  • Method conventions (ends with...)
    • ! changes internal state of object
    • ? returns boolean
  • do keyword -- optional loop keyword (unless on single line)
  • Crazy for loop alternatives
  • General delimited strings
  • Case statement
  • Lots of options for string element access and string substitution and insertion
  • Regular expressions as first-order objects
  • Perl-like control flow constructs that can be tacked onto the end of an expression

Tuesday, December 11, 2007

"Why don't you write a Facebook Application?"

There is a lot of hype surrounding the newly released Facebook application platform. Developers are falling all over themselves to get a product rushed out the door, funding for Facebook apps is flowing in from VCs and you can even take a class in Facebook application development at Stanford. Amid all of this irrational exuberence, I find myself frequently getting asked why I don't write to it. Well, there are a lot of good reasons to stay as far away from the platform as possible. It's proprietary, unpredictable, not a level playing field in the least and crowded with unworthy offerings. My time and effort is much better spent somewhere else.

First of all, even if we assume for the sake of argument that I am interested in developing a Facebook app, the deck is stacked against me. Tim O'Reilly points out that there is a steep drop off in users after the first four or five most popular apps (the graph on O'Reilly's page is instructive). There are a few reasons for this. The first is that the door has largely closed on the willingness of users to add new applications or suggest them to their friends; the fad has come and gone. In other words, "[W]e must acknowledge that ... users have grown accustomed to a small subset of applications available to all users, and the exploratory period has come to an end... Facebook is all about communicating an image of yourself to your peers, and unless someone creates a truly captivating, innovative, or better F8 application, no one is going to adopt it on a whim." The quickest functional and moderately compelling apps to get out the door were the ones that users pounced on. The second reason for the disparity in users parallels the disparity in the finances and professionalism of the makers of the apps. Five of the top six apps right now are made by just two companies: Slide and RockYou!. [A] Making little flash widgets is essentially these companies' entire business and both of them are well financed. Amateur developers do not stand a chance against a small army of VC-backed Flash coders who do this for a living. [B] Any entry into the Facebook app market now is essentially futile.

The survivability of the Facebook platform is another issue. It bears some eerie similarities to "walled garden" initiatives past. Perhaps most illustrative is the case of AOL, whose proprietary platform, of course, nobody uses anymore. Should I really bother developing against a technology predicting that it won't survive 10 years? Perhaps, but I would rather write to a platform that is built on open standards. Jason Kottke explains: [E]
As it happens, we already have a platform on which anyone can communicate and collaborate with anyone else, individuals and companies can develop applications which can interoperate with one another through open and freely available tools, protocols, and interfaces. It's called the internet and it's more compelling than AOL was in 1994 and Facebook in 2007.
The fact that Facebook could change its platform or go out of business at any time is a disincentive to write a Facebook application. I don't like my creations functioning at the whims of Facebook or its investors; it's a better bet to go with an established, open platform.

I ran across a similar post on Facebook app suckiness that raised an additional reason not to develop a Facebook app. If, against all odds, your application is truly innovative and distinguishes itself in the crowd of petty profile pollution, you still are on Facebook's turf; that carries some important consequences. Specifically, Facebook could copy your idea with a feature that they subsequently build in to Facebook itself. It will be accessible to all users, not just the ones that choose to add it as an application, and there will be no use for your app anymore. Facebook could take your idea and reimplement it, thus sucking away all of your users, and there would be nothing you could do about it.

Then there is the embarrassing stigma of being in the company of Facebook application developers. The (many) applications are written by developers who want to jump on the Facebook hype bandwagon. Most of them are amateurs, and it shows. Take the Quizzes application, for instance (ranked 14th in most active users, so a reasonably popular app). It lacks basic functionality that one would expect in such an application: namely, the ability to see the correct answers after you take the quiz. It also creates a quiz that other people can take before you even indicate you are finished adding questions! Furthermore, I couldn't access the application at all today because, presumably, it is choking under the load that Facebook is sending to it (another all-to-frequent problem of these applications). Quizzes, admittedly, might be an application that one might use occasionally. I can not say the same about other applications, most of which can be broken down into four categories:
  • Horoscope
    • What flower are you? -- "Are you rose, lilly, foxglove, daffodil, nigella, sunflower, violet? Find out."
    • Birthstones -- "From the time gemstones were discovered, they were believed to have mystical powers and attributes that could be passed to the wearer. The red of ruby was fiery and passionate; cool blue sapphire was calm and composed. What's yours?"
    • Psychic Breeze - Psychic Readings and Fortune Telling -- "Accurate psychic, psychic medium and clairvoyant readings are available today. Our extraordinary psychics, mediums and clairvoyants use their psychic ability to provide you with guidance in relationships, love, finances, and other life hurdles."
  • Decorative trinkets
    • Snow Globe Gifts -- "Snow Globe Gifts! Send your friends realistic, shakeable, snow globes..."
    • Christmas Music Tree -- "Create your own special Christmas Tree. Decorate your tree with your friends and make them play many famous Christmas songs. It's your Musical Christmas Tree."
    • My Fab Bag -- "Buy and give your friends designer handbags. Choose your favorite to carry and display on your profile."
  • Finding a boyfriend
    • Likeness UNRATED -- "Find out who you're like on mature topics like purity, vices, and the seven deadly sins. Can you find a perfect match?"
    • Will you KISS me? -- "Send kisses to loved ones, lovers, romantics, mistresses and everyone! Ever wanted a friend or crush to kiss youand find that they want to kiss you too What if it happens on a Full moon night? Give and take kisses"
  • Just good ol' pestering people
    • Zombies -- "Bite your friends and make them zombies! Mmmmm... Brains! Also - you can fight Zombies, Vampires and Werewolves now!"
    • Vampires -- "From the makers of Zombies comes Vampires! Kind of like Zombies. Except that the vampires are hot. VERY hot. Also - you can fight Zombies, Vampires and Werewolves now!" [C]
    • X Me -- "Tired of just poking? X me opens up a whole new world of action-based messaging, for example 'Hug Her, Slap Him, Tickle Them!'"
Is this trash what I really want to spend my time developing? Do people actually waste their time using this filth? It's depressing that humans' frontal lobes have not yet developed sufficiently to resist soliciting the advice of fortune-teller applications. [D] Given this kind of crowd, I don't think I could expect anyone to take me seriously if I told him I was developing a Facebook application. I would anticipate him laughing in my face.

That's why I don't develop for the Facebook platform: it's pure hype. Nothing of significance has been produced in the form of a Facebook application, and the only applications that get any views are ones that are made by companies who specialize in them. This environment exists at the whim of Facebook and its investors, and could come crashing to a halt if the business goes belly-up or Mr. Zuckerberg has a change of heart. I'll take my code somewhere else, thank you very much.

===========================

[A] Prepare for some awful, awful music and graphics if you go to RockYou!'s page. I had the displeasure of being aurally assaulted by Lil' Mama blowing kisses at me. You have been warned.

[B] To hammer this point into the ground, RockYou!'s CEO discusses here how, in order to prepare for an expected spike in traffic, they ran around filling a 24-ft truck full of servers and hooking them up over a weekend. Does this sound like the kind of thing you could pull off with the change you found under the sofa? I didn't think so.

[C] "From the makers of Zombies..." As if Zombies was a fantastic, useful product to stake their reputation on. They have WereWolves, too. Maybe there's more, I didn't care to look.

[D] And there's a hell of a lot more dumb applications, if you want to take a peek.

[E] He expands on the "Facebook as AOL" theme in this post. Scott Rosenberg also has his thoughts on the subject.

Why I am Still on Facebook

Facebook sucks. And yet, I can't bring myself to terminate my account. It has a few essential features that I just could not do without because of its dominant position as today's preeminent social platform. Like the AOL of yesteryear, everyone else uses it (a bit too much) and expects you to use it to communicate with them. These few communication and sharing features are the site's strengths. Facebook counts on users sticking around in order to use these features regardless of how many ads they plaster on their pages or how many privacy violations they can rack up. Facebook's flaws are outweighed by its utility, which is why I haven't quit Facebook... yet.

Facebook's best feature is what it started out as: a directory of contact information. The average person does not have the time, skill, interest or money to register a domain name, set up a personal web page and push it to the top of Google's index for searches against his name. A social networking page is a much more convenient way to disseminate contact information. Facebook is the best solution for this because it shares contact information only with people of which the person approves. This arrangement makes many more comfortable than if they had shared their contact information on a public site such as MySpace. As Facebook also started out as a college network about the time that I was in college, it is the platform of choice of virtually all the people I would desire to contact. Most of the time, the aggregate contact information for someone just starting their professional life is not available anywhere else. I can not count the number of times when I quickly needed to contact somebody, only to realize that I did not have her AIM screen name, email address, phone number, etc and fetched the information off Facebook.

The other killer feature of Facebook is photo sharing, which is why it is now the largest photo sharing site in the United States with over a billion pictures. If I were to withdraw from Facebook, I would no longer have access to my friends' photos and they would no longer have access to mine. Of course, I could always migrate all of my pictures to Flickr or some other site and then point all my friends there. But is it really worth the time and effort to do that, knowing that Facebook already has a great framework for doing this that my friends and I currently use? Again, Facebook's privacy controls are also an important feature: if I transitioned to another platform, I would need to re-implement the privacy controls there (assuming they were even supported!). Additionally, all of the tag data and comments that Facebook supports would be lost in translation.

And let us not forget the networking part of social networking. Facebook does provide opportunities to network, in the business sense. [A] It's easier to approach a person if he looks familiar, you have some background on him and you can draw from a number of topics of conversation. Also, even if the only contact two people have is seeing each others' name go by on their respective News Feeds and having the other's face pop up once in a while on sample friend lists, that connection is sufficient to leave a lasting impression on the subconscious mind. [B] And requesting someone to be a friend on Facebook can be sometimes interpreted as a digital 'good meeting you' compliment. In spite of all this, I believe the networking aspect of Facebook to be a relatively minor incentive for staying on the site.

So photos and contact information are really the only two things that keep me from ending my adventures with Facebook. For the time being, it seems that I'm just going to have to swallow my pride, eat my words and keep using the site.

=============================

[A] "Expanding one's social network or sphere of influence by initiating mutually advantageous new relationships with people." (link)

[B] I didn't come up with this theory, my friend Monique did.

Monday, December 10, 2007

Facebook Sucks

Every time I sign on to Facebook, a little part of me dies. Not only am I usually wasting my time, but I am allowing Facebook to violate my privacy, potentially offending hundreds of "friends" and being bombarded with ads and spam. Furthermore, I am forced to use Facebook's clumsy tools to communicate with others on Facebook who seem to never have heard of email, all while wading through the ostentatious posturing of Facebook's users. In short, Facebook sucks.

Facebook is a great opportunity to offend people. As if I didn't have enough trouble minding my etiquette in the real world, the choice to friend or not to friend (or grant restricted access, or defriend) provides daily chances for someone accidentally or intentionally insult someone else. The heart of the problem is that some people have different conceptions of what a Facebook friend actually entails. Does it mean you are friends in real life? Is it meaningless? Some are willing to Facebook friend total strangers and others keep a very small circle Facebook friends that might actually be closer to the number of good friends they have in real life. There is a point at which this managing of digital networks becomes tiresome, evoking a social network fatigue. The value of a particular user's experience on Facebook (or on any social network) rises and then falls as the number of users increases. [B] At first, the user is excited to connect with all of his friends and perhaps reconnect with some that he had lost touch with. But over time, as more people join the site, more time is spent on fending off unwanted friend requests and friend network management. This eventually drives the user to become much less active on the website, if not to opt out of it completely.

Facebook is a black hole that sucks up time. There is certainly something compelling about browsing your "social network" through a hyperlinked photo yearbook. In fact, it's too compelling -- some have complained of "Facebook addiction." Facebook exacerbates this problem (well, certainly not a problem for them) by sending you incessant reminders of activity on your account by default ("Someone has done x to you on Facebook") which pull you back to the site again. [A] Apps have worsened this addiction because now every app requires its own micro-management and sends its own messages to your inbox. Here is a picture of the overwhelming number of annoyances a typical Facebook user might face upon login. All of the time spent on Facebook wouldn't be wasted if there was substantive communication taking place on the site but, for the most part, there's not. It's all just about how many people you've converted into zombies or whether you identify more with pirates or ninjas.

Facebook reinvents the wheel in a variety of ways, moving online communication a step backwards. Since Facebook wants you to stay within the site's walls, Facebook provides tools for you to accomplish certain goals, no matter how mediocre those tools may be. For example, Facebook provides a "Marketplace" for users to buy and sell items on their site. Of course, there are many superior auction/barter/market sites already on the Internet: Amazon.com, eBay and Craigslist, to name a few. Facebook provides "Posted Items" and "Notes," whose features are poor substitutes for nearly any blogging platform. And Yahoo and Google groups are many times more advanced than Facebook's groups. The most irritating example of Facebook's compulsive re-engineering is Facebook messages -- it reminds me of a dark age when GMail didn't exist, and also gives me another inbox to manage (much more clumsily, mind you).

Twice Facebook has disregarded its responsibilities to its users and precipitated privacy invasions, both for which Zuckerberg promptly issued apologies. First there was the News Feed, which broadcasted users' actions to all of their friends. Facebook followed that with Beacon, a system that tracked a users' actions on affiliate sites, such as the New York Times, and then fed information back to Facebook (and that users' friends through the News Feed) about a users' behavior. Twice Facebook has recklessly played fast and loose with its users' data, and twice it has pushed its audacity to the limit until it faced a revolt by its users. The most shocking part of this whole story is that these systems never went away! In each instance Zuckerberg waved his hands to make an apology, as if users' concerns had been assuaged, and only partially disabled the systems that caused the uproar. The News Feed, although it did get some controls, still doesn't give the user a choice if some types of stories are broadcasted. Beacon is also wholly intact, but was changed from an opt-out to an opt-in system. [C] There is no reason to think this is the last time this pattern will happen, as Scott Rosenberg points out. To justify its massive valuation, Facebook is under a lot of pressure to find additional ways to monetize its service, and there is good money to be made selling out users. What privacy-infringing "feature" will Facebook be pressured to invent next? [D]

And then there are ads -- lots of ads. In addition to the easily blockable banner ads on the bottom and sides of the page (an Internet staple since as far as I can remember), Facebook has devised ways to deliver ads to users that are not so trivially thwarted. Facebook actually embeds ads inside the News Feed that come from the same server as the rest of the News Feed, unlike other embedded ads (like Google's) which come from a third-party server and are thus easy to identify and block. Fortunately, there are some ways to rid your eyeballs of these menaces. It is also much harder to tell that you are looking at an ad in the news feed: Facebook blends them in so well to almost make them indistinguishable from bona fide News Feed stories. This approach is in stark contrast to what Google and other sites do, clearly identifying which content is sponsored and which content is not. This practice is irritating at best and deceptive at worst.

And speaking of deceptive ads, how about using my image in an ad for a sponsor, as if I were sending a personal recommendation to a friend? Taking a "social action" (as Facebook puts it) is not a license to use me as a viral marketing stooge for Blockbuster, et al. [I] To add insult to injury, Facebook is now allowing advertisers to send targeted emails directly to your Facebook inbox (the first line of the most recent one I received from CbsSports.com: "Hey College Hoops Fan!"). Hm, unwanted emails in my inbox trying to sell stuff; I think that's better known by its more conventional name -- spam. You spam your "friends" with application requests, corporations spam you with messages in your inbox, your "friends" spam you with pokes and news feed items. This is essentially what Facebook has become: a very efficient platform for spamming people.

You can put a lot of data in to Facebook, but getting that data out is an entirely different story. It is quite easy, for example, to import your contacts from another platform into Facebook. Facebook, however, provides no convenient method for exporting those contacts into Outlook, Gmail, or the other social network flavor of the week. The same goes for photos, videos and all other multimedia. Looking for a "backup my photos" link? Sorry, it doesn't exist. There are ways to get data out of Facebook, but they are inconvenient and few. One is to use the API either by writing an app yourself (clearly out of the reach of most users) or using an application like FriendCSV [K]. The API, however, doesn't allow extraction of some types of information, like email. Another is to scrape the site, which is against the terms of use (like most companies') and can lead to the termination of your account if they catch you doing so. And it is also impossible to get Facebook to delete your information from their servers, even if you quit using the site! Facebook is not only a black hole for your time, but also for your personal data.

Facebook has become the victim of its own success: phishers are starting to use the site as a launchpad for attacks. Phishers embed links on a user's wall that point to a malicious domain that harvests their names and passwords for Facebook. This, in turn, can lead to more phishing attempts as well as stealing other credentials (such as banking login information) and/or spamming for pharmesuticals, etc. Of course, no site is immune from the scrutiny of attackers, so this is hardly Facebook's fault. As a commenter on the Wired blog puts it, "Anywhere there is popularity and potential profit, there will be hackers and scammers." However, it is notable that criminals now see Facebook as a lucrative target. Facebook needs to crack down on these activities if it expects users to continue to feel comfortable using it. [J]

Perhaps this isn't the fault of Facebook per se, but a lot of the people on Facebook are really annoying. You know the ones I'm talking about. The coward who thinks that the epitome of activism is clicking a button that says "Join Group." [E] The gullible student that believes the world will be changed by joining groups with titles like "For every [number] people that join this group, I will donate [amount] to [cause]." [F] The narcissist that ceaselessly uploads pictures of themselves and her friends partying and broadcasts her status message to the world at least ten times a day. The clueless folk carrying on what, prior to Facebook, would have been a private conversation on each others' walls. [G] And people that have way too much free time giving each other gifts [H] and engaging in poke wars (or now, thanks to SuperPoke, throwing cow wars or the like). Facebook is often a cesspool of narcissism and ignorance that I could do without.

It may come as a surprise that, despite all of these grievances, I haven't terminated my Facebook account. It is true that I still grudgingly sign on to the service at least once a day because it provides some tangible benefits that no other service offers. Regardless of its flaws, I haven't quit Facebook... yet. I intend to write two follow up articles to this one, the first discussing what Facebook gets right and the second as an answer to "Why don't you write a Facebook application?" Stay tuned.

Update: I'm finally getting off of Facebook. The straw the eventually broke the camel's back for me was the sheer unusability of the site. Nearly every page load on Facebook maxes out my processor (on a decent machine). It's not just the sheer load of crap that Facebook is bringing into each page; even the most basic user actions cause my browser to lock up. For example, entering characters into a text box (for commenting on a photo or sending an email) has a delay of several seconds between when I hit the keys on the keyboard and when the letters show up onscreen. These inexcusable bugs plague the site. Congratulations, Facebook, you've finally driven me away.

=========================

[A] Yes, I know you can change this in your settings. Yes, I know that they now send the contents of messages in the email as well. Everything else, however, still gets you the same information-void kind of notification that begs you to come to Facebook if you want to find out what was actually said.

[B] I'm certainly not the first person to identify this phenomenon, by the way. I'm not sure who, if anyone, is the right person to attribute this to. Thoughts?

[C] And who knows what Facebook thinks "opt-in" means? The devil is in the details: does not clicking on an "I don't want this" indicate the user wants to participate? Zuckerberg, upon Beacon's release, already had some interesting ideas about what "opt-in" meant.

[D] Ed Felten provides an excellent Beacon post-mortem here.

[E] Some think that the best way to protest Facebook's practices and policies is to join a group whose cause is to recognize the fact that all its members dislike a new feature. It's not. The best way to protest is to delete your Facebook profile.

[F] A frequent question I ponder when I see groups like this is, why do people waste their time supporting these groups if they have zero assurance that the donation/action/whatever will actually happen?

[G] I really, really don't need to know the day-to-day private details of your life. And I REALLY don't need them broadcasted to me in my News Feed. If you're negotiating a play date with your friend, take it off Facebook! If you're dumping your boyfriend, take it off Facebook!

[H] Perhaps these do serve a cause since Facebook donates $1 for most of them to charity. But it annoys me when it is implied that there is some kind of scarcity to information, playing to misconceptions about the Internet. Okay, pet peevey rant over.

[I] In the legal sense, as well: could this practice be illegal?

[J] It is also a testament to the cleverness of the phishers (and the nature of Facebook's users) that they are using such well-targeted bait in the text for their links: "lol i can't believe these pics got posted.... it's going to be BADDDD when her boyfriend sees these,"

[K] Careful, FriendCSV's creators try to sign you up for their own social network when you use their product. How hypocritical, offering a way out of someone else's frying pan and into their fire.

===================================
UPDATES:

Facebook is sharing too much data with application developers. (Link)

Facebook, in violation of their privacy policy, is now sharing your personal data with Microsoft. Hm, does that have anything to do with taking $240 million of their money?

Facebook is arbitrarily removing applications that don't seem to be in violation of their privacy policy, a la Apple and the iPhone store. The victim this time? Burger King.

Facebook may be eliminating local networks, exposing more personal data to more people.

In a rare moment of good news, Facebook has agreed to abandon Beacon.

Another reason to stay off Facebook: STDs.

Tuesday, December 04, 2007

Code formatting

Here are some tools to make your code pretty (in Ubuntu repos):
For indent, I find that the following arguments seem to work well for code I write: -bap -bbb -bl -blf -bli0 -bls -cli3 -di1 -fca -hnl -i3 -ip0 -l80 -lc80 -nbbo -nut -nsaf -nsai -nsaw -psl

Monday, November 12, 2007

Blocking Facebook News Feed Ads with Greasemonkey

I hate ads, so I block them. If I want something, I'll search it out. I don't need marketers wasting my time trying to convince me that I need something I don't. Most of the time I have ads blocked by aliasing most known ad servers to 127.0.01 in /etc/hosts/. This only works when the ads are coming through a server that is listed in the file (say, ad.doubleclick.net) and not when the ads embedded in the page are served from the same server from which the original page was requested.

This is exactly the problem with the ads from Facebook, which just deployed a new ads system that has ads targeted on what you've listed in your profile. For example, if you listed Jane Austen novels as some of your favorite books, you might see text ads in the sidebar or in your news feed advertising "Jane Austen: The Ultimate Sappy Romance Collection" ... or something. So how to block these ads?

Greasemonkey is a Firefox (and IE, although I wouldn't know much about that :-) ) extension to inject arbitrary Javascript into web pages, meaning that you can manipulate a page, or parts of a page, automatically as you see fit. Its behavior is defined by scripts, many of which can be found at userscripts.org. If you're familiar with web design, you can write your own scripts quite easily. Mozdev has a good quickstart guide, and Mark Pilgrim has an online guide and a book if you want to research this further.

There are a few ways to do block Facebook's new ads. The first is using document.getElementsByTagName('div') to fetch all the divs in the page and then loop through them, testing them for known ad-serving attributes (for example, a className like 'social_ad_advert' (sidebar) or 'feed_item clearfix social_ad' (news feed) or an id of 'ssponsor', 'sponsor', or 'announce' (all banner ads)) [1] and then either hiding them with element.style.display = 'none' or removing the element entirely using element.parentNode.removeChild(element). A second is using XPath, which makes for much more compact code. [2] userscripts.org is awash in (mostly mediocre [3]) scripts to block Facebook ads, but the most comprehensive one I found was "Remove All Facebook Ads" which I'm using in my browser right now. The only suggestion I have for this script would be to use the window.addEventListener to trigger execution of the code rather than embedding it in an anonymous function, as explained in the quickstart guide (under "Tips").

Greasemonkey scripts are executed after the DOM is loaded, which means that all the ads will be fetched from their sources and displayed on the page before they can be stomped out, unfortunately. Therefore, to make the page load faster by not fetching and displaying ads in the first place, it would be wise to use an /etc/hosts blocking scheme instead of a Greasemonkey solution where possible. Greasemonkey should be used only as a last resort in combination with /etc/hosts where /etc/hosts can't block ads that aren't fetched from a server different than the one used for the requested page, as in the case of Facebook news feed ads.

[1] It would probably be faster to not test for the id matches and just using getElementById for those few cases outside of the loop instead (within try-catch blocks if the elements aren't guaranteed to be on to page and could potentially throw an error).
[2] I'm not sure about the efficiency implications of using one vs the other. Anyone care to comment?
[3] For instance, "Hide Facebook Ads" tries to do some browser detection... I'm not sure how large the market for IE4 Greasemonkey users is...

UPDATE:

Now using New Facebook Layout Ad Killer for the new Facebook layout

Argh, it seems Facebook has added another lame ad sidebar. Just extend the NFLAK script by looking for a document ID called 'fadbar' and hide it if it's there.

Wednesday, October 24, 2007

Gutsy (Ubuntu 7.10) Tweaks

Just upgraded to Gutsy from within Feisty, which took about an hour, and things look great, for the most part. But here's a few things just to make sure everything was in tip-top shape:
  • To enable Compiz Fusion, System->Preferences->Appearance->Visual Effects->Extra
  • Gutsy doesn't ship with the Compiz Fusion settings manager, and I wanted my old (Beryl) settings back... run sudo apt-get install compizconfig-settings-manager in a terminal to install it and ccsm in a terminal to launch it
    • Don't forget to create a new profile in Preferences or else you'll be screwing with the default settings
    • Personally, from the defaults I enable Rotate Cube, Paint fire, Water effect, Wobbly windows, Annotate, Splash, Cube Caps, Shift Switcher; I disable Expo; I tweak Desktop Cube (General->Multi Output Mode->One Big Cube) and Animations
  • Fonts on my system were oddly stretched out vertically. Here's a solution from this thread: edit the line in /etc/gdm/gdm.conf that says -command=/usr/bin/X -br -audit 0 to say -command=/usr/bin/X -br -audit 0 -dpi 96
  • The fonts still look a little screwy. I'm just going to bite the bullet and install the MS core fonts ... a HOWTO is here.
  • Download updates automatically in the background: System->Administration->Software Sources->Updates->Download all updates in the background
  • Synchronize your clock to NTP servers sudo apt-get install ntp
  • Autohide pannels: Right click on a panel->Properties->Autohide
    • Set how much of a panel can be seen when it is hidden: link

Tuesday, October 23, 2007

An Indictment of Apple, Part 1

Unless you have been in a cave for the past several years, you've probably noticed the increasing brightness of an odd, white glow that radiates wherever students, geeks or professionals congregate. That strange luminosity is the combined brilliance of the hypnotizing and stylish logos on Apple notebooks that everyone seems to be carrying around these days. It's no secret that Apple's hardware (and accompanying software) has been selling well recently, with its popular laptops, iPods, iPhones, etc. Everyone I know seems to be purchasing one of Apple's shiny toys: my family, my friends, my UNIX zealot colleagues and technoignorant acquaintances alike. The media constantly flatters Apple with positive reviews of its products, editorials praising CEO Steve Jobs' visionary genius and provides an extraordinary amount of marketing hype for its new products. Could this company possibly do any wrong?

The answer to that question is a resounding "Yes." It could, it can, and it does.

Apple's products have become a liability to own. They are often ladden with restrictions, break easily, frequently can not be extended by third-party developers and are, in some cases, just a prime example of bad design. Furthermore, it is perplexing that Apple's products continue to be so popular when superior alternatives exist. In this article, I will focus primarily on how a top-down culture of control inherent in Apple products decreases their value. I will address other issues in subsequent articles.

Some of Apple's problems stem from its desire for the user to have an experience using its product over which it has total control. Another way to phrase that would be that Apple wants you to lock you in to its product line, so that it can compel you to fork over your cash for the next edition of OSX or the newest personal electronic device. It is a culture of top-down control that, on the whole, does not benefit the user. For example, about a month ago new iPods shipped with a technical restriction that prevented them from working with other operating systems (Fortunately, the gtkpod developers broke the lock within days). Basically, Apple is saying to the consumer, "In order to use our products, you need to buy even more of our products. Otherwise, tough." Apple is similarly inconveniencing customers with iPod's ability to pipe video output to a TV: in order to use this feature, you need to either use a device with a built-in Apple authentication chip or purchase an Apple video cable for $49.

The recent tug-of-war between iPhone owners who want their pricey gadget to be as useful as possible and Apple's not-unless-we-approve attitude is an illustrative case in point. In case you haven't been following the news, Apple made a deal with AT&T so that it would be the exclusive carrier of iPhone voice traffic for five years and built technical mechanisms into the phone to ensure this arrangement. Naturally, customers of other carriers wanted to use the phone on the network they were already paying for, which meant they would have to hack the phone to get this functionality. Thus, the iPhone was hacked, again and again. Apple estimates as many as 250,000 people, roughly one sixth of iPhone buyers, have hacked their phone. In response, Apple released a firmware update to the phone which made the unlocked phones inoperable. Apple's consistent attempts to prevent its customers doing what they want with Apple products are an insult to its users' intelligence and detrimental to their ultimate experience with the iPhone. As Jon Lech Johansen puts it, "When Steve Jobs claimed the iPhone was 5 years ahead of every other phone, was he talking about the iPhone’s revolutionary handcuffs? In a world where open technologies are increasingly becoming the norm, Apple’s way of Thinking Different means marching in the opposite direction."

Apple is hostile to not only users' interests, but developers' interests as well. Will Shipley, a developer for the Apple platform, writes an excellent post about third parties' inability to put their applications on Apple's platforms. He explains that Apple's arrogant attitude is damaging its relationship with users and developers alike:
And the iPhone is a closed system, like the iPods before it, so third parties can only develop software for it if they are EXTREMELY close to Apple. This is an incredibly frightening trend. As Apple gets more and more of its revenue from non-Mac devices, they are also getting more and more of their revenue from devices that simply exclude third parties...

But with the iPod Touch, what's Apple's excuse for locking up the platform? Why can't I write programs for this device? Who might it hurt? Why is Steve announcing that he's playing cat-and-mouse with developers who intend to do so? Is Apple so far removed from its customers that even when the latter overwhelming votes for extending a device (by downloading iPhone programs in the hundreds of thousands), Apple's response is, "No, you can't do that. We know what you want, you don't. You want AJAX apps, you just don't know it yet."

That sure reminds me of the old, crappy Apple. The one that almost went bankrupt because of its hubris.
When Apple disallows third parties from writing to its platforms, then everybody suffers. The users suffer because they don't get to use the added functionality of their devices, the developers suffer since there are less opportunities to extend Apple's software and Apple suffers because less people buy their gizmos and consumer relations are soured. Innovation often doesn't happen at the center -- it happens at the edge, and Apple does not have a monopoly on good developers or good ideas.

Apple's poisonous politics don't stop at simply excluding developers from its platforms -- they permeate the very coding tools engineers use to create. I submit to you the bizarre incidents of Apple crippling both the dtrace and gdb versions on OSX. Both programs' source contain uncommented portions of code that disallow low-level examination of certain Apple-built programs, including iTunes. These suspicious lines are not in any other version of these utilities on any other platform. Why Apple did this is anyone's guess -- it seems rather stupid to try and outwit many extremely talented programmers who will inevitably discover these unpleasant surprises (as they did). What is certain is that Apple's handicapping of OSX versions of open-source tools make Macs a less attractive purchase for developers.

Now we turn to iTunes and its accompanying Digital Rights Management (DRM), which is quite the antithesis of Apple's "It just works" slogan that it uses to push its products. iTunes has an elaborate system of "Authorization" that limits the number of computers on which one can play their music. To play a song from another computer, you must get that computer to "authorize" yours. which requires it dialing Apple HQ to ensure that this is all right with Mr. Jobs. If you don't happen to have a network connection at that point, you can't make this connection and thus can't play your friend's music -- tough luck. Of course, only a total of 5 computers can be authorized per source computer, so if your friend has already authorized the limit, he'll have to de-authorize someone else (perhaps even himself, which is allowed -- revoking the right to play songs he paid for via the iTunes store on his own computer... the gall of Apple amazes me!), at which point that person who was just de -authorized will start wondering why she can't play certain songs on her computer. What a mess. I find it repulsive, not to mention inconvenient, that I need to ask a corporation's permission to listen to certain songs in certain ways.

iTunes also has a bad habit of rolling back its already limited functionality with its frequent 'upgrades.' iTunes 4.5 decreased the amount of CDs one can create with a single playlist from 10 to 7 and also detected and blocked similar playlists. iTunes 4.7.1 took away the previous ability to stream music to anyone on a local network. One wonders when the march towards never being allowed to play any music anywhere will stop. And let's not forget the insidious 'features' that Apple included in iTunes from the very beginning: the draconian measure of embedding user data into songs [1] they purchased (presumably as a deterrent against file-sharing) and restricting iTunes-purchased songs to be played the iPod only to the exclusion of all other digital music devices. [2] [3]

I can already hear the Apple faithful clamoring that all of these malfunctions are not the fault of Apple, but the fault of the record companies whose music Apple licenses. Even Steve Jobs wrote a much-cited article which put the blame for DRM at the feet of the RIAA constituents. This "They made me do it" excuse, as John Lech Johansen points out, is quite lame because Apple both refuses to open up FairPlay (its DRM scheme) to other companies and applies DRM to songs whose labels do not require their songs to be DRMed. Not to mention that other online music services have managed to operate without DRM just fine. Amazon can do it, Magnatune can do it, why not Apple? For a very good reason: Apple profits from the lock-in that DRM provides them (see Johansen's article for some telling quotes from Apple employees). Apple is today's main proponent and user of DRM at the same time that it makes overtures declaring its wish to end DRM once and for all. This is pure hypocrisy. If you hate DRM so much, Mr. Jobs, then put your money where your mouth is and take all the DRM (in its many shapes and forms) out of your products. Apparently Apple's CEO prefers cash in his pocket to shooting straight with the public.

Apple loves controlling how people use its products. Unfortunately for Apple, users often don't like being told exactly how they are supposed to use their computer, digital music player, et al. And people extremely dislike having unnecessary restrictions placed on products for which they paid a substantial amount. Limiting and sometimes rolling back the functionality of a company's products (and therefore angering customers and third-party developers) is not a winning strategy in the long term. Apple would do well to abandon it.

------------------
Footnotes
[1] I also responded to many posts on the linked Lifehacker discussion board. It's amazing to see how willing people are to let Apple dictate right and wrong to them. I also wrote about this on one of my other blogs.
[2] Makes me all the more embarrassed that I wrote a gushing article about iTunes for a school magazine when it came out as a freshman in college.
[3] I'm not going to even go into more reasons why you shouldn't install iTunes (especially on Windows). See iTunes spying on you and bloat and ugliness and what exactly does ituneshelper.exe do?. I'm sure there's more.
-------------------
Updates
  • Apple has continued its controlling ways with the iPhone App Store: they are actively restricting the applications that people can download, even after they have been released live to the public. An application that allows one to tether a PC to an iPhone connection is an example. BoxOffice is another. I'm sure there will be dozens more.
  • iPhone development is the biggest Apple money-maker I have ever seen. To simply write programs for an iPhone and get them uploaded to the iPhone store, you have to buy three things from Apple: 1) Some kind of Apple Computer (one to two grand) 2) an iPhone (two hundred to six hundred dollars, depending on when you bought it, to say nothing of the AT&T connection fees which account for the majority of cost) and 3) an enterprise or standard development license ($299 and $99, respectively). You can not develop on anything else besides an Mac. You can not develop without a license for the SDK. With all of these restrictions, you've just put around two to three thousand dollars into Apple's pockets.
  • With regards to the iPhone App Store, Apple is no longer banning only apps that they consider unacceptable in some way (see above) but also those that contain duplicate functionality. Not only that, but Apple has been notifying developers of their rejection with a letter that has a non-discolsure agreement on it -- according to Apple's lawyers, one can't even talk about the details of why he was rejected.
  • Here's an interesting reason to kill an iPhone app: it's using up too much bandwidth. But that's just what Apple did to streaming audio app CastCatcher.
  • Apple traffics in deceptive advertising. On the company's online store, supposed 'photos' of products are actually hand-generated drawings that misrepresent certain features of the products. Furthermore, Apple has been forced to pull an ad that grossly exaggerated the browsing speed of the iPhone.
  • Taking user oppression to the next level, Apple is now arguing that jail-breaking your phone is illegal under the DMCA.
  • The last place you would expect DRM to be is in headphones, but alas, Apple has put DRM in its headphones as well (false alarm)
  • Apple has outlawed Project Gutenberg from the iPhone because some of the books contain pornographic material. Could this get any more ridiculous? Yes, they are now censoring a dictionary.
  • Apple is working on technology to detect when a customer violates the warranty. Essentially, your device tells Apple what you have done with it when you bring it in for repair. Apple already has deployed liquid submersion detectors in some of its hardware.
  • Apple, not AT&T, blocked Google Voice on the iPhone
  • The iPhone secretly tracks your location
  • Apple has joined Facebook in shutting down Palestinian-related apps