Tuesday, October 31, 2006
Annologger Update: now with microformats and iCal
It's been long overdue, but I've added features that I've wanted for some time--mainly microformats and iCalendar. iCalendar isn't fully featured yet, meaning if you subscribed to it using your outlook calendar, you cannot update your annolog from your outlook calendar. That said, I'm working on it, and trying to keep the code base organized and healthy, so that it's not a mess that can easily be broken. It's like cleaning up your kitchen as you cook.
So while it might not look like much, there have been some minor bug fixes and major refactoring to get these features in. Thanks for the feedback so far, and keep them coming. :)
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
Thursday, October 26, 2006
Time can be needlessly complicated
International standard date and time notation
To think that of all things I could have picked to build, it was something centered around time. Having worked on a sunrise/sunset and moonrise/moonset calculator, you'd think that I would have learned my lesson.
Time is difficult because there's always exceptions to the rule, and some specifics are unclear on first thought.
Does midnight belong to the beginning of the day, or the end? Is the end date and time of an all day event inclusive or exclusive? It ends up that luckily, there were plenty of smart people that thought about all of this decades before I came about, but they like to write in a boring prose, in specs like ISO8601.
By the way, midnight belongs to the beginning of the day, and all day events have exclusive end times. However, that's not what people mean when they say they're going to iceland from october 18th to october 22nd. When people say that, the date is inclusive. Aye.
And do you store all times in UTC? Depends on the application. Throw in time zones, there's even more confusion, not to mention taking day light savings into account. And if you really want to get nitpicky, there's always leap years and leap seconds to think about.
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
To think that of all things I could have picked to build, it was something centered around time. Having worked on a sunrise/sunset and moonrise/moonset calculator, you'd think that I would have learned my lesson.
Time is difficult because there's always exceptions to the rule, and some specifics are unclear on first thought.
Does midnight belong to the beginning of the day, or the end? Is the end date and time of an all day event inclusive or exclusive? It ends up that luckily, there were plenty of smart people that thought about all of this decades before I came about, but they like to write in a boring prose, in specs like ISO8601.
By the way, midnight belongs to the beginning of the day, and all day events have exclusive end times. However, that's not what people mean when they say they're going to iceland from october 18th to october 22nd. When people say that, the date is inclusive. Aye.
And do you store all times in UTC? Depends on the application. Throw in time zones, there's even more confusion, not to mention taking day light savings into account. And if you really want to get nitpicky, there's always leap years and leap seconds to think about.
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
Saturday, October 14, 2006
Enumerable still...
Still playing around with Enumerables. It was almost not worth mentioning, but it's a short post. I was looking for a short way to read in a file's contents all into memory all at once. Normally you wouldn't do this, because it eats up memory if you do it this way. But my files were short.
This will open up a file README and return the entire contents as a string. It's pretty cool, since I don't have to muck around with temporary variables much...and it's readable...well, if 'inject' makes sense to you. Also cool is that, like Java container classes, as long as you implement 'each' in your Ruby class, you get all the ones in Enumerable for free. You just have to include it.
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
File.open('README', 'r') do |file|
file.inject { |contents, line| contents << line }
end
This will open up a file README and return the entire contents as a string. It's pretty cool, since I don't have to muck around with temporary variables much...and it's readable...well, if 'inject' makes sense to you. Also cool is that, like Java container classes, as long as you implement 'each' in your Ruby class, you get all the ones in Enumerable for free. You just have to include it.
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
Friday, October 13, 2006
Screencast of Annologger
Screeniac � Annologger.com
I'm usually pretty busy so I don't search often on the web for what people have been saying about Annologger. But for the first thing that I put out, it's both a bit exciting and apprehensive to hear about it.
I had a really hard time choosing a name for it. To this day, I'm still not quite satisfied with the name, but apparently, people get what it is. So that's good news.
And secondly, it seems easy enough to use, so people seem to get it. I've had a lot more japanese users lately, (presumably from this review and others), and they seemed to put more stuff on there than 'test'.
But all in all, I need to put in the other features that I've been dying to get done, so people get see what its potential is.
Time to get back to work.
I'm usually pretty busy so I don't search often on the web for what people have been saying about Annologger. But for the first thing that I put out, it's both a bit exciting and apprehensive to hear about it.
I had a really hard time choosing a name for it. To this day, I'm still not quite satisfied with the name, but apparently, people get what it is. So that's good news.
And secondly, it seems easy enough to use, so people seem to get it. I've had a lot more japanese users lately, (presumably from this review and others), and they seemed to put more stuff on there than 'test'.
But all in all, I need to put in the other features that I've been dying to get done, so people get see what its potential is.
Time to get back to work.
Tuesday, October 10, 2006
Singleton classes not seemingly the same as Singleton pattern
So I was looking at someone else's code today, and I saw this:
Huh? What did "<< self" mean? I guess I didn't read my Ruby book closely enough. It's apparently a "singleton class", which doesn't seem to be exactly a "singleton pattern".
A "singleton class" is a sole metaclass that 'holds' methods for a single object. It would have been called a 'metaclass', except that it's not the class of a class, but a class of a class that only exists for that one object.
Keep in mind that this is the case because you can add methods to objects in ruby at runtime. Since everything in Ruby is an object(even the classes), it has to go somewhere, and in an anonymous metaclass is where it goes.
One can almost think of them as 'static' methods in Java. However, because objects can be added methods at runtime, they don't necessarily belong in the class, but to the metaclass of an object that only belongs to that object.
They're not like 'static' classes of Smalltalk or Java. You can call self (like this in Java) in Ruby's 'static' methods.
It's a curious construct because you can use it to specify 'static' methods all in one go. It's the equivalent of the following:
Apparently, you can also use it to do prototype factories. There's more to it than meets the eye. You can find better explainations here and here.
Ruby is weird.
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
module Formats
class BasicNestedFormat
class << self
def foo
...foo code...
end
end
end
end
Huh? What did "<< self" mean? I guess I didn't read my Ruby book closely enough. It's apparently a "singleton class", which doesn't seem to be exactly a "singleton pattern".
A "singleton class" is a sole metaclass that 'holds' methods for a single object. It would have been called a 'metaclass', except that it's not the class of a class, but a class of a class that only exists for that one object.
Keep in mind that this is the case because you can add methods to objects in ruby at runtime. Since everything in Ruby is an object(even the classes), it has to go somewhere, and in an anonymous metaclass is where it goes.
One can almost think of them as 'static' methods in Java. However, because objects can be added methods at runtime, they don't necessarily belong in the class, but to the metaclass of an object that only belongs to that object.
They're not like 'static' classes of Smalltalk or Java. You can call self (like this in Java) in Ruby's 'static' methods.
It's a curious construct because you can use it to specify 'static' methods all in one go. It's the equivalent of the following:
module Formats
class BasicNestedFormat
def self.foo
...foo code...
end
end
end
Apparently, you can also use it to do prototype factories. There's more to it than meets the eye. You can find better explainations here and here.
Ruby is weird.
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
Thursday, October 05, 2006
The need to write code, the need to ease reading
Lately, I've been doing more thinking, reading, prototyping, and moving, than I've actually been writing code. One of the things that got me thinking enough to write this post was the classic syndrome of software developers and engineers to be gripped by the "Not invented here" syndrome.
Some would say that's because engineers and developers like to create. That's part of it too, but I think it's also partially because we only get better if we write things ourselves. The only way to learn about something fully is to actually do it. The problem is, a lot of things that we would learn by doing, has already been done for a while now. Beyond linked lists and parsers, most anything you can think of has already been done. Not that we can necessarily do it better, but doing it is half the fun, and it's the only way you can get better.
Another aspect that compells people to write things themselves is that
But that doesn't mean that there can't be language constructs to faciliate the ease of reading code. Python does it as a language choice that restricts whitespace. Maybe the computer doesn't care about whitespace, but people surely do.
I have recently found that iterators with descriptive names actually help in reading code. Instead of a generic for or while loop, it kinda helps to have collect, and inject.
It would be nice if code was self-documenting, meaning that you would be able to tell what the code was doing from what the method names and variables were, rather than the comments around it. It would be nice if method signatures were all you needed to know what to put into a method (and no, static typing doesn't help completely here). I wonder if language constructs could help out with it, or would we always need to rely on the stylistic tastes and discipline of the individual programmer to write readable code and documentation?
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
Some would say that's because engineers and developers like to create. That's part of it too, but I think it's also partially because we only get better if we write things ourselves. The only way to learn about something fully is to actually do it. The problem is, a lot of things that we would learn by doing, has already been done for a while now. Beyond linked lists and parsers, most anything you can think of has already been done. Not that we can necessarily do it better, but doing it is half the fun, and it's the only way you can get better.
You won't become a better programmer by passively studying other people's code. Similarly, you don't magically become a better writer by reading a lot of books. You become a better writer by.. wait for it.. writing. - Jeff AtwoodSo it's a balancing act between using other people's code and reusing code to be more productive, and writing your own to learn and reduce dependencies.
Another aspect that compells people to write things themselves is that
It's harder to read code than to write it. - Joel S.I think it's because code, like math, like poetry, is dense. There are meanings and implications that aren't literal and aren't at the surface. There are implications for what gets written at every line, and relies on a culture and context behind it to fully understand it. This is why it's hard to read math equations, Alexander Pope(first one that came to mind), and much less code.
But that doesn't mean that there can't be language constructs to faciliate the ease of reading code. Python does it as a language choice that restricts whitespace. Maybe the computer doesn't care about whitespace, but people surely do.
I have recently found that iterators with descriptive names actually help in reading code. Instead of a generic for or while loop, it kinda helps to have collect, and inject.
It would be nice if code was self-documenting, meaning that you would be able to tell what the code was doing from what the method names and variables were, rather than the comments around it. It would be nice if method signatures were all you needed to know what to put into a method (and no, static typing doesn't help completely here). I wonder if language constructs could help out with it, or would we always need to rely on the stylistic tastes and discipline of the individual programmer to write readable code and documentation?
Wilhem has built Annologger, a tool that lets people worship your dentist appointments.
Looking for cumulation in Ruby?
Module: Enumerable
This is pretty basic, but I only recently discovered it. I have a task that I do often in code. Usually, there is some list of things that I'd need to go through, and tack it on to another list if it meets some condition.
The same problem appears when I try to summate all the things that fit some condition. I dislike having the initialization there in the beginning. Is there a better/prettier way? I would have thought collect() would be it, but it is mapping one value for another. It's almost like a function in math--a certain input gives you a certain output.
So it was finally that I saw inject(), and it seems to be what I want.
I think that'll work. The difference doesn't look like much, but somehow it bothers me when I have that floating assignment before the loop. It's easy during maintainance that someone moves 'funny_posts=[]' far away from the loop, when semantically, it's a part of how the loop will work correctly.
inject() also applied to cases where you're trying to find the maximum in a list.
I guess it's the difference between functional programming and procedural...using return of value instead of relying on side effects. I use to write off functional programming as something that was antiquited, but now, I'm finding gems here and there in functional programming. It makes me wonder how procedural took off so rapidly. Perhaps programmers think easier in procedural programming?
Update: I guess I should read Enumerable more closely. The example I had with collecting funny posts is done with a method called partition() in Enumerables.
This is pretty basic, but I only recently discovered it. I have a task that I do often in code. Usually, there is some list of things that I'd need to go through, and tack it on to another list if it meets some condition.
funny_posts = []
posts.each do |post|
if post.is_funny?
funny_posts << post
end
end
The same problem appears when I try to summate all the things that fit some condition. I dislike having the initialization there in the beginning. Is there a better/prettier way? I would have thought collect() would be it, but it is mapping one value for another. It's almost like a function in math--a certain input gives you a certain output.
So it was finally that I saw inject(), and it seems to be what I want.
funny_posts = posts.inject([]) do |funny_posts_thus_far, post|
if post.is_funny?
funny_posts_thus_far << post
end
end
I think that'll work. The difference doesn't look like much, but somehow it bothers me when I have that floating assignment before the loop. It's easy during maintainance that someone moves 'funny_posts=[]' far away from the loop, when semantically, it's a part of how the loop will work correctly.
inject() also applied to cases where you're trying to find the maximum in a list.
# find the longest word
longest = %w{ cat sheep bear }.inject do |memo,word|
memo.length > word.length ? memo : word
end
longest #=> "sheep"
I guess it's the difference between functional programming and procedural...using return of value instead of relying on side effects. I use to write off functional programming as something that was antiquited, but now, I'm finding gems here and there in functional programming. It makes me wonder how procedural took off so rapidly. Perhaps programmers think easier in procedural programming?
Update: I guess I should read Enumerable more closely. The example I had with collecting funny posts is done with a method called partition() in Enumerables.
Sunday, October 01, 2006
The names of things
In a number of fairy tales and old legends, the name of a fairy, a monster, or a god was pivotal to the story. 'To know someone's name is to control them', it is said. I actually never gave it much thought growing up. How silly. What's in a name? A Rose by any other name would smell just as sweet.
But when it comes to ideas and concepts, a name is pretty important. Naming a variable, class, or method correctly means that there's some convention the reader of the code can go by to be able to infer how to use it. It's a type of documentation.
So when it comes to finding names for things, I have a hard time. How are 'agreements' and 'disputes' related? Are agreements and disputes the same type of thing? If so, what is the name of that thing? Or are they not the same type, but merely the same thing in different states? An agreement is the alignment of opinion between two parties where a dispute is the disalignment of opinion between two parties?
How about the person that 'seconds a motion'? What do you call that person? What do you call the person that brought up the motion in the first place?
When I think about it, public method signatures should be well designed, so that, like well designed tools, it should be obvious how to use it. However, 'obvious' comes with a background and context, and even culture.
Update:
According to wikipedia, A person that makes the motion is a mover. The person that seconds a motion could be called a supporter. And according to my lawyer and english major friends, agreements and disputes are apples and oranges, apparently. agreements and disagreements are more on the same type.
But when it comes to ideas and concepts, a name is pretty important. Naming a variable, class, or method correctly means that there's some convention the reader of the code can go by to be able to infer how to use it. It's a type of documentation.
So when it comes to finding names for things, I have a hard time. How are 'agreements' and 'disputes' related? Are agreements and disputes the same type of thing? If so, what is the name of that thing? Or are they not the same type, but merely the same thing in different states? An agreement is the alignment of opinion between two parties where a dispute is the disalignment of opinion between two parties?
How about the person that 'seconds a motion'? What do you call that person? What do you call the person that brought up the motion in the first place?
When I think about it, public method signatures should be well designed, so that, like well designed tools, it should be obvious how to use it. However, 'obvious' comes with a background and context, and even culture.
Update:
According to wikipedia, A person that makes the motion is a mover. The person that seconds a motion could be called a supporter. And according to my lawyer and english major friends, agreements and disputes are apples and oranges, apparently. agreements and disagreements are more on the same type.
Subscribe to:
Posts (Atom)