This post explains the terminology I’ve come
up with after two weeks working in Net::FluidDB.

There’s no Perl in this post because albeit my laboratory is said
module what I want to communicate are abstractions, not some particular
implementation. We talk here about nouns and
verbs, and introduce a model to some extent.

Note the focus is on a chosen terminology, this post does not explain the
involved concepts themselves. The high-level
docs explain FluidDB as such.
<h2>Objects</h2>

We start with objects. Objects are the central entities
in FluidDB. They have an id, which is a meaningless
UUID, and an about attribute, which is an optional
arbitrary string.

An object knows the paths of the existing tags on it, that’s a set
of strings called tag_paths. The following section
explains what is a tag and a path.
<h2>Tags</h2>

The next most important entity in FluidDB is the tag.
For example, “fxn/was-here”.

Tags have a description, which is a string attribute,
and can be indexed, a boolean. They have also an
object, explained later.

Tags have a path, “fxn/was-here”,
and a name. The name is the rightmost fragment of the
path, “was-here” in the previous example.

Each tag belongs to a namespace. Namespaces are
explained later.

To tag an object you associate a tag and (optionally)
a value to it.

In an object-oriented language tagging an object could look like
this:

object.tag(rating, 10)

The method name is a verb, and the first argument is a
tag.

A library may provide a convenient way to tag an object given a tag
path:

object.tag("fxn/rating", 10)

There “fxn/rating” acts as an identifier, it points to the
tag with that path, if any. In fact that’s what the REST API asks for, but
that’s low-level stuff, the schema we are presenting runs at a higher
level.

In a dynamic language you can have such a dynamic signature. In a
statically typed language you would probably have different methods for
different signatures. But that’s not important for the mental model we
are building.

Tags in FluidDB are not typed. You could tag an object as
having an “fxn/rating” of 10, and tag another object as having
an “fxn/rating” of “five stars”. Values are
typed.
<h2>Values</h2>

Tagging involves an object, a tag, and optionally a
value. Values are typed. There’s some technical
stuff related to encodings and such, but for the purposes of this post I think
we do not need to go further.
<h2>Namespaces</h2>

To organize tags FluidDB provides
namespaces.

Namespaces have a description, which is a string
attribute, and an object, explained later.

Namespaces can contain other namespaces, and tags. Tags cannot, tags
are leaves.

The namespace_names attribute of a namespace is
the possibly empty set of the names of its children namespaces. The
tag_names attribute of a namespace is the possibly
empty set of the names of its tags.

Each namespace that is not top-level has a parent. A
concrete implementation may define the parent of a root namespace to be
some sort of null object.

Any namespace has a path, and a
name, akin to tags. The namespace with path
“fxn/reading/books” has name “books”. Its
parent has path “fxn/reading”, and name
“reading”.

You can compute the path of any child namespace or tag from the path
of the containing namespace and their respective names.
<h2>Permissions</h2>

Each possible action on each existing tag and namespace has
a permission associated with it. A permission consists of
a policy and an exception list, to be
applied to a certain category and
action.

The policy may be open, or
closed, and the exception list is a set of usernames.
(Note: FluidDB in general lacks ordered collections, read “set”
when you see “list”.)
<h2>Policies</h2>

Each possible action on tags and namespaces have a default set of
permissions. When you create a tag or a namespace, each one of the possible
actions gets such defaults. Each of those defaults is called by definition a
policy.

There’s a name clash here which is not good. It is inherited from
the API. I’ve departed in some places from the API, but I believe we
need to stick to it in this case: A policy consists of a
policy and an exception list, to be
associated with certain category and
action on behalf of a certain
user.

The policy attribute may be open or
closed, and the exception list is a set of usernames.
(Note: FluidDB in general lacks ordered collections, read “set”
when you see “list”.)
<h2>Users</h2>

Users have a name, a username,
and an object, explained in the following section.
<h2>Where are the IDs?</h2>

If you are familiar with the API you may be wondering where did the IDs
of tags, namespaces, and users go, and what are those objects
I’ve mentioned.

Tags, namespaces, and users are not FluidDB objects
themselves. They have no ID, they have no about, you can
delete them.

The proper identifier of a tag or a namespace in the system is
their paths, and the one of a user its username.

FluidDB, however, creates an object for each tag, namespace, and user.
They can be found in their object attribute. So, for example, if you
wanted to tag the user whose username is “fxn”
there’s a canonical object in the system for it. You can
tag that object, but you cannot tag the user itself.

If the user is deleted, the corresponding object is not. Remember,
objects are immortal. In particular if the user was tagged the tags are still
there, with the object that represented it in FluidDB. This parallels the object
for any other thing in life that once existed.

Testing for format.js like that often suffices, but strictly
speaking
this is not testing if the request is Ajax. As everything else, abusing some
logic is fine as long as you know what you are doing.

You know an Ajax call is just a fancy name for an ordinary HTTP call that
is performed
from JavaScript. Ajax requests sent by any of the major JavaScript
frameworks include
an HTTP header that distinguishes them:

X_REQUESTED_WITH: XMLHttpRequest

Thus, the proper test to detect Ajax calls checks that header, and this is
what
request.xhr? does.

On the other hand, Ajax calls do not expect JavaScript necessarily.
Remember, they
are ordinary HTTP calls, so they may ask for HTML, JSON, whatever. What
you ask for
goes in the HTTP Accept header. For example Ajax functions in
Prototype send by
default:

Accept: text/javascript, text/html, application/xml, text/xml, */*

And that is something format.js tests for (in addition to an
optional
explicit format parameter somehow encoded in the URL). If the Accept
header
starts with "text/javascript", or "application/javascript", or
"application/x-javascript" you'll get routed into format.js.

Note that even link_to_remote with the :update
option is routed to
format.js. That is fine from the HTTP point of view, because
the header says
it is OK to send HTML, but is kind of weird to serve HTML from within
format.js
isn't it?

But you can set whatever Accept header you need, jQuery provides even
some shortcuts
like "xml", which tells the library to send

Accept: application/xml, text/xml, */*

So, in practice format.js kind of works, but both tests are not
equivalent:

An Ajax call asking for "text/xml" is xhr? but won't be
routed through
format.js.

A call triggered by an ordinary SCRIPT tag that reaches your
application (perhaps
it serves dynamic JavaScript) is routed through format.js,
but it is not
xhr?.

That being said, if I control the interface and know what's what I am
personally fine
using format.js. Routing through respond_to is
concise and clean,
and you may know that in that action the only expected JavaScript calls
are Ajax.
If that holds you are still not testing for true Ajaxness but are testing a
sufficient
condition, which is correct anyway.

In Ruby 1.8 strings have no encoding associated, they are only
a handful of bytes from Ruby's view. Regexps are agnostic in that
sense as well they match bytes against bytes. Unless you pass one
of the flags /u for UTF8, /s for SJIS, or
/e for EUC-JP. By the way note that /s in Ruby
has a different meaning than in Perl,
and it is
not the only flag that conflicts.

If you set $KCODE to "u" then source code itself
is assumed to be UTF8 and Ruby turns the /u flag on. Ruby
on Rails does that since version 1.2 for example.

AFAICT it is not clearly defined which support does Ruby 1.8 provide
for Unicode in regexps. For example Flanagan & Matz have little
about it except for some vague descriptions. You could say it is just
not supported, but some things do work. For example, it is a known
trick that counting /./ matches gives you the length of a
UTF8 string, whereas #length returns number of bytes.

A couple of important bits with definitely partial support are the
character classes \w and \s (and thus their
negations
\W and \S).

In general, the definition of a word char depends on the locale. In
Catalan "ò" is a word char. Regexp engines are
locale-aware and the meaning of \w depends on it. That is,
\w is equivalent to [a-zA-Z0-9_] only in ASCII-like
locales. In Ruby, if source code is UTF8 and /u is enabled
"ò" matches \w.

That's important of course, a Rails application that validates domain
or account names against \w for example is permitting
accented
letters. If they should not be allowed you need to write the character
class explicitly: [a-zA-Z0-9_].

On the other hand, since "ò" and friends match \w
you could be tempted to validate Unicode against \w, I
certainly
have beed more than tempted :-). Wrong! There are characters that
match
but shouldn't. For example "¿" or "¡", or
"·".

With whitespace there's also poor support.
NEL (U+0085) belongs
to \s,
but it doesn't in Ruby 1.8. A string that consists of NELs not only
is not blank in Rails, but it in addition matches \w in
Ruby
1.8! Two gotchas for the price of one!

If you need proper Unicode support,
among
other
goodies, you switch to using Oniguruma. That's the regexp engine
used
in Ruby 1.9, which is available for 1.8 as a gem:

I don't know whether the interviews in this video can really be
extrapolated,
but
my instict says there's something into it. When you are into technology you
need
to look ahead and construct the future, but a corner in your head has to keep
you
balanced and take into account the man in the street is very very far from
your view. Just a reality check, your duty is to be ahead, as is the duty of any
specialist in any field.

PS: I saw this video in a post of Seth Godin, which uses it to depict an
unrelated point.

Almost a year ago I started to work on a script to count the number of
people that have contributed to Ruby on Rails, the aim was to be able to give
a good approximation in my keynote at Conferencia Rails 2008.

That's not a direct count because since Subversion does not track
authors credit was given by hand following a few conventions. The committer
typically put
your name/email/nick whatever at the end of the commit message for
example. Even
nowadays with Git the author of a commit to Rails is not always the Git
author, some munging is still needed for fine tracking.

So the script identified authors where day appear, and normalized the
names to identify every handler, typo, etc. and map them to a "canonical"
name.

I am very happy that effort took shape in the official Rails Contributors index,
with
design by José Espinal.
It has
been online for a while but didn't blog about it yet.

$WORK

After three years from its foundation I left ASPgems at the beginning of
June. I have no plan B, it was simply something I felt I had to do.

I have done some contract work for the rest of June but I am currently
taking a break with my family in the seaside. I am gonna have fun with my
daughter in the beach, read, sleep, walk, ride our bikes, open source, and
take perspective to think what's next.

SRUG is very very happy about the outcome, we put effort and organised
the conference with illusion, and people felt it and had a really great time.
Talks were interesting, and most important people had the chance to chat, sit
in the grass, go to the beach at night....

We were honoured Matz came to the conference to give the opening
keynote, he made a 22-hours flight from Japan! We tried to make him feel at
home. Matz actually attended the conference, I mean, you know those stars
that give their keynote and then go to do sightseeing. Not Matz, he stayed at
the conference and talked with everytbody, we was at the
conference and if you took a perspective of the hall he was mixed with the
audience as any other attendee. Hat tip at him.

Next year EuRuKo goes to Kraków, our best wishes to the
organisers. We
met them in Barcelona and we are sure they are going to run an extraordinary
conference.

and perl executes it right away, directly. There's no intermediate file
being generated or anything. Sounds like magic unless you know what's a
source filter.

But some people don't get that even with the work behind this module,
the test suite, etc. this module is just a fucking joke! That's why it belongs to
the
Acme:: namespace in the first place.

It is a joke about taking programming languages too seriously, to the
hell with that, there you have Python and Perl mixed together. Sublimation.
Climax. You can put
that code against a wall and do vipassana contemplating it, release your
attachments to this mundane world!

Rails has now an official documentation team! That's Pratik, Mike, and me. I
am very happy this converged this way, there has been a great deal of work in
docrails and Rails Guides that finally takes
shape.