Monday, January 24, 2011

Napping and memories

http://www.cosmosmagazine.com/news/3982/memories-take-hold-better-during-sleep

Friday, January 21, 2011

HTTP: safety and idempotency

This blogpost has lots of useful links and a good example.

A big part of RESTfulness is mapping CRUD (Create/Read/Update/Destroy) to GET/POST/PUT/DELETE without violating idempotency (repeatability) or safety (no side-effects).

As pointed out here, using GET unsafely does not break anything, but I think the author misses the point. GET safety is a convention, which makes it easier for the rest of us to understand Web APIs. It's similar to conventions about identifying side-effects in software. The trouble is that most software engineers do not recognize the cognitive penalty of side-effects, so they do not see any reason to illuminate them.

Also, note the difference between idempotency and referential transparency. Technically, we should say referentially transparent, rather than idempotent, since the result of a GET (or PUT or DELETE) cannot be applied to itself. To me, that's a less important distinction than the tenor of the rule. And here is a lucid defense of using idempotent in the context of the web.

See also this StackOverflow discussion, especially the link to Roy Fielding's comment on REST and Cookies.

Thursday, January 6, 2011

jQuery: WTF?

Unbelievable.

I definitely prefer Prototype. Still, jQuery is much better than ASP. (Fortunately, the folks at MS recognized this, and VS MVC has supported jQuery since 2008.)

RoR: Nested routes

I learned something interesting enough that I want to keep a link to it. Unfortunately, I posted the answer a year after the question, so nobody will ever see it. Awwww.

Thursday, December 30, 2010

Ruby: Inconsistencies

This is a growing list:
  • String#concat
    • Should be String#concat!
    • I guess it's meant to resemble #insert, #delete, #fill, #replace, #clear, etc., but I wish those had "!" too, like #compact!, #reject!, #slice!, etc. There should be 2 versions of all these, but because there is no "!", the non-mutating versions can never be.
  • Hash#update is a synonym for Hash#merge!
    • I have to remember which one has the "!"
    • Hash#invert does *not* mutate. How do I remember all this?
    • Even worse, Set#merge (no "!") mutates, unlike Hash#merge.
  • Set#add? and Set#delete?
    • These mutate.
  • s.chomp!.upcase
    • Can fail, since String#chomp! can return nil
  • Array#fetch(i) (and Hash#fetch(k)) can raise IndexError
    • Should be Array#fetch!(i)
    • Block and multi-arg version could drop the "!"
  • String#each does not exist in Ruby1.9, while #each_char does not exist in 1.8
    • We cannot write forward-compatible code!
    • Soln: s.split("")
  • '0x10'.hex and '0x10'.oct are same, but
    • '010'.hex and '010'.oct are different
  • Given: a = [1,2,3]
    • a[2] == 3
    • a[3] == nil
    • a[4] == nil
    • a[2,1] == [3] (and a[2,2] == [3] as well)
    • but a[3,1] == []
    • while a[4,1] == nil
  • For Arrays
    • a[x,y] = [nil] substitutes the slice
    • a[x,y] = z     substitutes [z], but ...
    • a[x,y] = nil   deletes the slice! (fixed in 1.9)
  • inspect/to_s
    • There used to be a clear distinction, like Python's __repr__/__str__, but 1.9 often (though not in all cases) erases that useful distinction.
  • Array   Float   Integer   String 
    • Those are Kernel functions, not constants.
  • ...
Also see Ruby Best Practices, a great book.

Wednesday, December 29, 2010

Ruby: Introspection

Supposedly, Ruby has introspection, but some things are missing. For example:

# How to get the name of the current method?
# Add this snippet of code to your logic somewhere
 
module Kernel
  private
  # Defined in ruby 1.9
  unless defined?(__method__)
    def __method__
      caller[0] =~ /`([^']*)'/ and $1
    end
  end
end
In Python, this is not much better:

import tracebackdef asdf():
    (filename,line_number,function_name,text)=traceback.extract_stack()[-1]
    print function_name
asdf()

Update: __method__ is part of Ruby as of 1.8.7.

Here is something else rather awkward in Ruby:

# Print all modules (excluding classes)
puts Module.constants.sort.select {|x| eval(x.to_s).instance_of? Module}
In Python, we could simply do this:
import sys; print sys.modules.keys()
Ruby's introspection (also) reveals a lot about the structure of classes.