Ruby Symbols are not Lisp symbols
With all the rage for reasons whatsoever about Ruby and its Symbols,
people often start to compare Ruby symbols with Lisp symbols. Don’t
do that, it’s just wrong.
Ruby symbols are not Lisp symbols!
There are at least six important differences:
For Lisp symbols, the Common Lisp Hyperspec
says
(in this post, Lisp is considered to be Common Lisp):
Symbols are used for their object identity to name various entities
in Common Lisp, including (but not limited to) linguistic entities
such as variables and functions.
Symbols can be collected together into packages. A symbol is said to
be interned in a package if it is accessible in that package; the
same symbol can be interned in more than one package. If a symbol is
not interned in any package, it is called uninterned.
About Ruby symbols, ri says:
Symbol objects represent names and some strings inside the Ruby
interpreter. […] The same Symbol object will be created for a
given name or string for the duration of a program’s execution,
regardless of the context or meaning of that name.
This is the first imporant difference: Ruby symbols are globally
unique, Lisp symbols can exist in several packages. This means that
there can be symbols in Lisp which have the same name but are
different: FOO and FOO will always be the same, but a symbol
FOO given in package A to a function in package B will not be equal
to FOO there. This can easily confuse newbies.
Second difference: Lisp symbols can be uninterned, whereas Ruby
symbols only exist when they are interned. (An exercise to the Ruby
curious: Find out how to check if a symbol with given name exists,
without interning it. Answer below.)
Third difference: Lisp symbols carry data, Ruby symbols only identify.
A certain Lisp symbol has two slots, a value cell and a function cell.
Since Common Lisp is a Lisp-2, a symbol therefore can “be” a
variable and a function at the same time. Ruby symbols aren’t
anything, but they can be used to lookup methods (but not local
variables, despite Ruby also being a Lisp-2… and for instance variables,
don’t forget the @).
Fourth difference: Lisp symbols have a property list, Ruby symbols
don’t (but you could add that). Imagine a Lisp property list like
instance variables in Ruby. Property lists often are used to attach
data to symbols (this was used for the first object-oriented
programming styles, a.k.a. “flavours” in Lisp, for example).
Fifth difference: Lisp symbols can get garbage-collected if they are
unbound, Ruby symbols stay alive forever. This can be considered an
implementation detail but has to be kept in mind if you intern a lot
in long running processes. (Don’t!)
Sixth difference: Lisp symbols are upcased automatically by default,
Ruby symbols are created as specified. Basically, foo and FOO is
the same in Lisp, but :foo and :FOO aren’t in Ruby. To create
something like :foo in Lisp, you’d need to write |foo|.
These differences make clear that Lisp symbols are rather different to
Ruby symbols, but there is one “exception”, the Lisp symbols of
package KEYWORD. Now, guess how these Lisp symbols are
created… exactly: with a leading colon. The Lisp symbol :foo
is a symbol called “FOO” in the package “KEYWORD”. Therefore, the
Lisp symbol created given by :foo always is the same as :foo.
Keywords are mainly used for keyword parameters (cf. Rails), where the
calling package often isn’t the definiton package.
I conclude:
Ruby symbols aren’t Lisp symbols, but Lisp keywords.
Answer to the exercise:
puts "U3ltYm9sLmFsbF9zeW1ib2xzLmFueT8geyB8c3wgcy50b19zID09IGdpdmVu
X25hbWUgfQ==\n".unpack('m*')
NP: David Gilmour—Terrapin
Nukumi2 0.5 released
Nukumi2 0.5 is released.
This is the second release of Nukumi2 since exactly this day last
year. Nukumi2.5 (or, for technical reasons, Nukumi2 0.5) is primarily
a maintenance release fixing some small bugs; the biggest change is
the switch from Needle to Dissident for dependency injection. This
change will require you to do a minor change in your config.rb.
Nukumi2.5 is one of the bug-fixing releases before Nukumi3, which will
never exist. Instead, Nukumi2.5 will slowly converge to
Nukumi2.5029078750, which is the second Feigenbaum constant.
What’s new in Nukumi2 0.5?
- Atom 1.0 support (thanks to Sebastian Vuorinen)
- Using Dissident for dependency injection instead of Needle
- Works with Ruby 1.8.3+
This release does not incorporate the Kashmir templating engine yet,
just because I lack the time to rewrite the templates.
You can get Nukumi2 0.5 at:
http://chneukirchen.org/releases/nukumi2-0.5.0.tar.gz
Merry blogging and a happy new year. :-)
NP: Bob Dylan—I Shall be Released
Making of: The XMasHack 2005
Maybe you already saw my yearly christmas greeting on ruby-talk:172428
(last year’s to be found here),
but today I’d like to explain how I did it. If you didn’t run it yet,
do that now and be amazed. ;-)
First of all, I needed to implement the actual logic. I’d only like
to outline it here and leave the rest for the reader. You may want to
read the complete, unobfusciated
source.
The real snowfall happens in snowdrop!, where a random vector of
snow heights gets increased by one in a way the difference to the
neighbour elements is never greater than one. This vector then gets
rendered in to_s onto a marshalled array with the greeting message
by differentiating the vector and thereby figuring out which chars to
use. Above the skyline snow randomly gets painted.
All this happens until all the vector’s elements are filled up. The
logic is not very difficult but I tried quite a few ways to make it
work best. I’d like to thank Frixon on #ruby-de for the inspiration;
he had to write the mountain algorithm in Ada (I didn’t look at the
code, only at the output).
Of course, that was the easy part. ;-) Now, the thing had to be
styled. Since this years hack was a lot bigger than last years (2221
byte), I couldn’t simply reuse last years fir
tree. I first tried to add some
thicker border to it, but then I thought it would be boring if I
used the same image twice.
So I took the PostScript star of
first advent, gimped it a bit (solid fill, rescaling to an appropriate
size and ratio since terminal fonts aren’t 1:1), then saved it into a
portable grey map and solarized it into ASCII chars using a
self-written script. The rest of the
image (border and snow) was made manually using Emacs’ picture-mode.
The final ASCII image, consisting of * and and some custom text
was then filled with code, using a similar
script like last year.
It was some hours of work, some hours of fun and I hope you enjoyed it!
NP: The Melvins—Revolve
Merry Christmas!
Frohe Weihnachten, ein schönes Fest, und einen guten Rutsch ins neue Jahr
wünscht euch Christian Neukirchen
Merry Christmas and a Happy New Year!
(source)
NP: Die Roten Rosen—Merry X-Mas Everbody
Marking up outlines: Tagged OPML
For a bigger school project I recently had to make some outlines. I
used the OPML Editor for that, because
it’s the only outliner I seriously can use (despite all efforts to
write one for Emacs on my own, but more on that below). After all, it
wasn’t a bad experience; the outlining is quick and straight-forward
and just works. The keybindings are comparatively sane, and the OPML
Editor is open source.
Then, I decided I would like to print out the outline. Hehe.
Of course, the OPML Editor doesn’t have a print function. I don’t
even expect that actually. However, the only way to get your data out
of it is the HTML export. Good, the HTML looks very basic, the HTML
is very unclean ([Winer rant suppressed]) and invalid. I also needed to
add a title because I had to turn it in.
Trying to do this the “Macintosh Way”… let’s copy the outline
(essentially, a nested <ul>) from Safari and paste into Pages. The
indentation got lost. Enough, let’s do it the “Unix Way” and edit the
generated HTML on my own. I hacked some <h1> in there and quickly
had it how I wanted it. Add some CSS styling and the thing is ready
to print.
The next time I had to prepare a similar outline, I thought that the
OPML Editor provides an almost perfect way to write. You can easily group
related paragraphs and so on. All it lacks is a way to declare some
outline entries to be shown as titles (and display them in a different
style), or as block-quotes or similar. With a bit of thinking on, it
would turn out to be a graphical
Vooly editor.
I looked around if someone already had that idea (apparently not,
which I think is interesting.) Essentially, what I wanted to do is
tagging the OPML entries, and the OPML
“specification” ([Winer rant suppressed])
even has the type= attribute that could be used for this
(alternatively, I’d have added one).
Marked-up Outline: An outline which entries can be of
different types and are displayed accordingly.
It’s a bit like that style selector known from popular
word-processing (yuck) applications.
Given a marked-up outline, useful things can directly be made from it:
A XOXO-version (a.k.a., [Winer
rant suppressed]) that has appropriate class= attributes and easily
can be styled using CSS however you want.
A properly typeset version for printing, for example using ConTeXt’s
XML facilities or some custom code to map the markup tags to TeX.
Filtered outlines, which only contain certain parts. This could be
used to work around limitations of
hierarchies.
and likely something nifty I didn’t think of…
Today, I decided to try implementing it, and dug into the OPML Editor.
This post was written using Emacs.
The display part of the OPML Editor is very hard to customize.
Basically, the only thing that can be changed easily is the icon next
to the entry, which is not enough for my purposes. If you have used
the OPML Editor, you may have noticed it actually does style basic
HTML (this was added in Frontier 7.0), for example it makes
<b>foo</b> look bold. I thought I simply could add my own tags to
that and only needed to figure out how to save the entry tags in the
model.
The model part turned out easy, every node can have certain attributes
that directly reflect the <outline> attributes of the corresponding
OPML.
But it’s impossible to set the font size and style per-node, at least
from UserTalk ([Winer rant suppressed]). The code that styles the
basic HTML actually is written in C ([Winer rant suppressed]) and
uncustomizable ([Winer rant suppressed]). Also, while searching for
that code, I found some code I rather wish I hadn’t seen.
No go. I don’t want to hack C and build my own version of the OPML
Editor just to make something like that possible.
I quickly looked into other means of editing outlines, especially
browser-based ones. The ones I liked were the free
sproutliner, Les Orchard’s
experiments and the
proprietary iJot. All of them are heavily
JavaScript-based and I couldn’t figure out an easy way to extend them.
If anyone wants to give that a try, by all means, do it!
For now, I’m deciding to go the “Unix way”. I’ll just add the entry
tags directly into the outline entry (still need to figure a
convenient syntax) and write some scripts to transform them to XOXO
and TeX. Also, I may revive my ideas about an new Emacs mode, because
with font-locking all that should be rather easy to do.
It’s a bit sad, I think quite a lot of people would have liked to have
an easy program that can be used to create valid and semantic HTML
documents based on some easy set of allowed elements…
NP: David Gilmour—Wish You Were Here
3. Advent
Dritter Advent, heute endet der Weihnachts^WChristkindlesmarkt in Biberach.
Weihnachtsstimmung kehrt zumindest bei mir trotzdem nicht ein, auch
wenn hier dauernd Die Roten Rosen laufen.
Vielleicht liegts am Schnee, der sich auch schon wieder
verflüchtigt/verflüssigt hat—trotzdem bleibt es kalt.
Letztes Jahr am vierten Advent haben
wir noch den Gefrierschrank enteist, diese Woche ging unsere
Kühlschranktür kaputt und es sah so ähnlich aus. Leider wieder kein
Bild gemacht, aber macht nix, man kann ja das von vor zwei Jahren
wiederverwenden.
Noch ein-einhalb Wochen bis zu den Weihnachtsferien.
Wenn Weihnachten das Fest der Liebe ist, warum ist dann Weihnachten
nur an Weihnachten?
— Engelbert Schinkel
Immer mehr Leute fragen mich, was ich zu
Weihnachten
will, hat jemand eine gute Idee?
NP: Die Roten Rosen—Ihr Kinderlein Kommet
Happy Birthday, lilith!
Just today, my iBook got one
year old. lilith, as it’s dubbed, still runs very well, despite of
being used just about every day and sleeping the rest of the time. In
fact, I can show all uptimes since last December (not counting
intra-day reboots):
12 + 19 + X + 19 + 30 + 73 + 106 + 53 + 45
The X represents one bad crash, if you make it 8 days, the sum would
be the complete year with 365 days. It think it’s pretty awesome to
own an computer that you reboot only nine times a year.

Of course, the case got a few scratches and you can see the places
where my hands rest, but it really doesn’t look bad for being used all the
year. Apple did a very good job, I once got the battery called back
because they feared it would get too hot, but else I there was nothing
to complain about. (Not that I’d complain about getting another
fresh, new battery for free. ;-))
Not that I would call myself a Mac user now, I still have a Debian box
around, and heavily use free software on the iBook. That is, I
probably can count the non-free non-OS X-default programs with my
fingers (and most are just convenience, if I’d go Debian again I could
quickly find replacements, but I don’t really see a reason for that.)
Panther is still fairly well supported (I don’t want to buy Tiger),
and while that is lasting, I have a very nice notebook that just
works.
Actually, I think the only problem I currently have with it is that
X11.app doesn’t work anymore after shutting the lid, maybe someone
knows what’s going on?
That said, if I had the money, I probably wouldn’t buy an 12.1" iBook
again, but instead get the 15” PowerBook everyone seems to own now.
And I wouldn’t buy that one if it had an Intel chip inside, either.
However, for a nice architecture that is well-supported by the things
I use, I’d spend a bit more money than usual.
And now, I shall hack happily until next year’s December 8.
NP: Dire Straits—Private Investigations
Tracing websites for fun (and profit?)
I recently stumbled on GotToZ.com, which
really is an waste of time but I looked like a challenge, so I tried
it for some minutes. The purpose of the site is to tangle through a
web of sites, each representing a letter of the alphabet, finally
reaching Z. I got up to Y manually, but then I decided Ruby could do
that much better than me. I encourage you to try it manually first,
though. (Not like you’re wasting enough time already…)
require 'open-uri'
@pages = {}
@count = Hash.new 0
def track(page)
return if @count[page] > 2
@count[page] += 1
a = (@pages[page] ||= [])
open(page).read.scan(
/\074A href="(http:\/\/.*?.com\/)".*?\076[A-Z]\074/m) { |e|
a.push e.first
}
a.uniq!
a.sort!
STDERR.puts page
a.each { |x| track x }
end
track 'http://www.amongothers.com/'
puts "digraph {"
@pages.each { |k, v|
v.each { |l| puts %Q[ "#{k}" -> "#{l}";] }
}
puts "}"
Run it, possibly a few times because I think the Z site is added
randomly (that’s why every page is fetched up to three times, too),
and save the standard output into a file. Now, you have a nice graph
you can run GraphViz on and do nifty
diagrams, like this (click for full 3884x3434 view, be careful):

NP: Dire Straits—Walk Of Life
Ballad Of A Thin Man (#ruby-lang version)
Excuse the longish post, but I was just part of something great on
#ruby-lang, I think this is even better than the zxy___ hack
. Enjoy.
20:14 <neoneye> hi
20:15 <slyphon> neoneye: nope! too unoriginal!
20:15 <slyphon> neoneye: now, let's try this again
20:15 <slyphon> neoneye: you walk into the room...
20:15 <chris2> with a pencil in your hand
20:17 <chris2> you see somebody naked
20:17 <slyphon> chris2: is this where it is?
20:17 <slyphon> chris2: who is that man?
20:17 <chris2> you try so hard
20:17 * slyphon just doesn't understand
20:17 <chris2> just what you'll say
20:17 * slyphon gets home
20:18 <chris2> something is happening in here!
20:18 * slyphon doesn't know what it is
20:18 <chris2> slyphon: do you, slypho^Wmister jones?
20:18 * chris2 raises his hand
20:18 <chris2> is this where it is?
20:19 * slyphon points to chris2 and says "it's neoneyes"
20:19 <chris2> what's mine?
20:19 <slyphon> chris2: where? what is?
20:19 <chris2> OMG, am i here all alone?
20:20 <slyphon> chris2: there's something happening
20:20 <chris2> i dont know what it is...
20:20 <slyphon> do you? chris2jones
20:20 * chris2 hands his ticket
20:20 * chris2 looks around
20:20 --- slyphon is now known as the-geek
20:20 <chris2> =)
20:21 * the-geek walks up to chris2
20:21 <the-geek> chris2: how does it feel, to be such a freak?
20:21 <chris2> impossible!
20:21 * the-geek hands chris2 a bone
20:21 <chris2> something is happening here
20:21 <chris2> but i dont know what it is
20:21 <the-geek> do you? chris2jones
20:21 <chris2> i have many contacts
20:22 --- the-geek is now known as lumberjacks
20:22 <chris2> among #lumberjacks
20:22 <lagcisco> wereapple: all I need for now is just class methods
20:22 * lumberjacks gets chris2 facts
20:22 * chris2 imagines
20:22 --- lumberjacks is now known as slyphon
20:22 * slyphon has no respect
20:22 * chris2 gives a check to rubycentral
20:23 * slyphon 's been to the professors
20:23 <chris2> they liked my looks
20:23 <chris2> i was at ibm and we talked about sco
20:23 <slyphon> with #great-lawyers i disussed #lepers and #microsoft
20:23 <slyphon> hahahaha
20:24 * slyphon read The Great Gatsby
20:24 * chris2 has all pdfs of fitzgerald
20:24 <chris2> and read them
20:24 <slyphon> chris2: we all know
20:24 <chris2> something is happening in here
20:24 <chris2> but i dont know what it is
20:24 <slyphon> do you? chris2jones?
20:24 <douthat> did I come in at a bad time? :)
20:25 <slyphon> douthat: not if you like dylan
20:25 <slyphon> ;)
20:25 <chris2> slyphon: you need to be the sword-swallower now
20:25 <slyphon> ah
20:25 --- slyphon is now known as sword-swallower
20:25 * sword-swallower walks up to chris2 and then kneels
20:26 * sword-swallower crosses himself then clicks his high-heels
20:26 <sword-swallower> chris2: how it feels?
20:26 <chris2> here's your throat back, thanks for the loan
20:26 <chris2> something is happening in here
20:26 <chris2> but i dont know what it is
20:26 <sword-swallower> do you? chris2jones
20:26 * chris2 sees a one-eyed midget
20:26 --- sword-swallower is now known as midget
20:27 <midget> NOW!
20:27 <chris2> for what reason?
20:27 <midget> HOW!
20:27 <chris2> what does this mean?
20:27 <midget> YOU'RE A COW!
20:27 <midget> chris2: give me some milk or else GO HOME!
20:27 <chris2> something is happening in here
20:27 <chris2> but i dont know what it is
20:27 <midget> do you? chris2jones
20:27 * chris2 joins again
20:28 <chris2> coming from #perl
20:28 * chris2 frowns
20:28 --- midget is now known as slyphon
20:28 * chris2 puts his eyes in his pocket
20:28 * chris2 puts his nose on the ground
20:28 * slyphon thinks about kick-banning chris2
20:29 <chris2> against me coming around?
20:29 * slyphon thinks, unless he's listening to his ipod
20:29 <chris2> something is happening in here
20:29 <chris2> but i dont know what it is
20:29 <slyphon> do you? chris2jones
20:29 <chris2> *clap* *clap* *clap* :D
20:29 * slyphon bows and applauds and bows and applauds
20:29 * slyphon hugs chris2 :)
20:30 <chris2> Bob Dylan---Ballad Of A Thin Man (Live Version)
20:30 <chris2> (by accident :P)
20:30 <slyphon> totally :)
20:30 <technomancy> oh man.... i haven't listened to dylan in waaaay too long
Original lyrics:
Ballad Of A Thin Man
by Bob Dylan.
NP: Bob Dylan—Ballad Of A Thin Man (Live Version)