Monday, January 24, 2011
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.
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.)
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.
- ...
Wednesday, December 29, 2010
Ruby: Introspection
Supposedly, Ruby has introspection, but some things are missing. For example:
Update: __method__ is part of Ruby as of 1.8.7.
Here is something else rather awkward in Ruby:
In Python, this is not much better:
# 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
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:
In Python, we could simply do this:
# Print all modules (excluding classes) puts Module.constants.sort.select {|x| eval(x.to_s).instance_of? Module}
import sys; print sys.modules.keys()Ruby's introspection (also) reveals a lot about the structure of classes.
Saturday, December 18, 2010
Web: Optimizations
- How To Debug Web Applications With Firefox
- How To Optimize Your Site With HTTP Caching
- How To Optimize Your Site With GZIP Compression
- How To Speed Up Your Javascript Load Time
Subscribe to:
Comments (Atom)