Jay McGavren's Journal

2008-03-29

Client, server, client environment, server environment...

OK, here’s part of what I’m thinking…

#Ensure server is authority on object movement by default.
def test_server_movement_authority
	@server.start
	@client.connect
	@client_environment << @object
	server_object = find_matching_object(@object, @server_environment)
	#Move client object one way, server object another.
	@object.vector.pitch = 90
	server_object.vector.pitch = 180
	#Interact.
	@server_environment.interact
	#Ensure client location/vector matches server's anyway.
	assert_equal(@object.vector, server_object.vector)
	assert_equal(@object.location, server_object.location)
end

Basically the client runs its own environment to keep things looking smooth, but when the server finally gets back in touch with it (and it could be several seconds), any location and vector the server sends gets blown away on the client. (It won’t send all of them, just those within a given update area.)

Read more...
2008-03-28

iTunes-style folder organization...

Hrmmm, not bad:

irb(main):001:0>
Utility.cache(
	'foo',
	:creator => 'Jay McGavren',
	:title => 'Cache Test',
	:sort_order => 1,
	:parent_directory => '.',
	:extension => 'txt',
	:album => 'My Album'
)
=> nil
irb(main):002:0> puts find "Jay McGavren"
Jay McGavren
Jay McGavren/My Album
Jay McGavren/My Album/01 Cache Test.txt
=> nil
irb(main):003:0> puts cat "Jay McGavren/My Album/01 Cache Test.txt"
foo

[edited for legibility]

Read more...
2008-03-28

Delayed require statements...

I have a set of Ruby utility libraries in my home directory for my own use, and it’s nice not to have to care how bloated it’s getting. Except that it was taking up to 10 seconds for even basic operations.

The main problem was my strategy of “require libraries first, ask questions later” (which is the exact opposite of my strategy when I intend to distribute something). My goal was to load everything up so I didn’t have to think about which modules I needed (or type their names). But even if all I was calling was a little file slurping routine, I got date parsing and PStore and a bunch of other stuff I didn’t need.

Moving my require statements within the methods that use them alleviated things quite a bit. Ruby doesn’t care when you load your modules, so why take the hit at startup?

def Utility.clipboard
	require 'win32/clipboard'
	Win32::Clipboard.data
end

A similar strategy is working nicely with Rake. I want to offer amenities like rSpec and ruby-prof tasks, but don’t want to make them requirements. So I don’t even define the task until I load the library successfully:

begin
	require 'spec/rake/spectask'
	desc "Run user stories"
	task :stories do
		FileList["stories/*.rb"].each {|f| ruby f}
	end
rescue LoadError => exception
	warn "Could not load rSpec - it might not be installed."
end

I’ve encountered acolytes of various languages who like to declare their dependencies right at the top of a file for all to see, and that’s a good thing. But dependency declaration is starting to move into the package your source comes in (gems, POMs, etc.), so I don’t think it’s such a big deal to have it in the source any more. If anyone knows of a pitfall I’m missing, though, I’d be interested to hear about it.

Read more...
2008-03-26

Why not to put abbreviations in your code:

-It hampers searches later. You might search for “database” and miss all the references to “db”. -It thwarts anyone for whom English is not a first language. “Config” doesn’t appear in Webster’s, much less an English to Japanese dictionary. -Even within the same routine, you lose time and concentration trying to think whether you used “char” or “chr”.

The benefits far outweigh the time cost of a few extra keystrokes. (Unless you can’t touchtype properly, in which case you should learn.)

Read more...
2008-03-24

Yes, they have headings when you sort by message size in Outlook...

Size: Large (100 - 500 KB) Size: Very Large (500KB - 1MB) Size: Huge (1 - 5 MB) Size: Enormous (>5 MB)

Read more...