Subscribe

Some D on Linux Progress

I’ve spent some time looking at D again and really trying to evaluate it’s fitness for MMO game development. There’s a lot of holes left still in the whole development picture. The IRC channel has been a really great source of information, and is generally a fun place to hang out.

It might seem like a small thing but a huge milestone I’ve hit recently is getting a full tool chain running patched gcc-4.1 and gdb-6.5 with D support. Here’s a sample call stack from a crasher I’m investigating in phobos. Notice that it has the correct line numbers and all the D symbols are correctly demanged. This isn’t the case if I use stock dmd or gdb.

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1211786352 (LWP 19585)]
0xb7dcccbc in memcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0  0xb7dcccbc in memcpy () from /lib/tls/i686/cmov/libc.so.6
#1  0x0805ac8e in _adDupT (ti=@0x806381c, a={length = 134815743, ptr = 0xb7c72c1f})
    at ../.././libphobos/internal/gc/gc.d:1045
#2  0x08055a25 in std.stdio.readln(std.c.stdio._iobuf*, inout char[]) (fp=0xb7ea1440, buf=@0xb7c5932c) at ../.././libphobos/std/stdio.d:447
#3  0x08055aaa in std.stdio.readln(std.c.stdio._iobuf*) (fp=0xb7ea1440)
    at ../.././libphobos/std/stdio.d:281
#4  0x0804a218 in main.ConsoleThread.run() (this=@0xb7c5bb00) at main.d:37
#5  0x08053620 in std.thread.Thread.threadstart() (p=0xb7c5bb00)
    at ../.././libphobos/std/thread.d:988
#6  0xb7eaa46b in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#7  0xb7e2e6de in clone () from /lib/tls/i686/cmov/libc.so.6
(gdb) 
Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

No related posts.

Austin Ruby Meetup 1-17-2008

We had a good time at the meetup tonight. Steven and I busted out the laptops and shared some code and ideas. He had a nice rails app for learning Latin that supported a tagging architecture. I know next to nothing about rails so it was interesting to see the interactive console and scaffolding at work. We talked a bit about lisp compilation, writing, philosophy and open source vs. closed source. I demonstrated how you can specialize a method in SBCL using THE type declarations and the difference it makes in the generated machine code via DISASSEMBLE. As usual it was entertaining and enriching. If you’re in the Austin area and want to talk Ruby, Lisp, Python, C or whatever you should consider joining us.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

Pipe Directories Over SSH

My good friend Jayk showed me this nifty trick years ago for moving directories over ssh:

From a local directory to a remote directory:

tar -zcf - . | ssh name@host "tar -zvxf - -C <destination directory>"

From a remote directory to a local directory:

ssh name@host "tar -zcf - -C <source directory> ." | tar -zvxf - 

This works by causing tar to read from stdin or write to stdout “-f -” and piping the results through ssh using the ‘execute command over ssh’.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

This last week I’ve spent primarily putting out fires and fixing issues in TR. Seems that everyone has woken up from their eggnog and shopping induced comas and realized that we need to get a solid release out the door. A break was needed and the excitement and drive of the team is evident now around the office. It’s obvious by the amount and quality of feedback that everyone around work has been playing a lot and listening to our player-base. I’ve spent a lot of my time just listening and participating in global chat. Even when they’re obsessing about Chuck Norris there are some great ideas flowing.

I’m extra happy with my team as we have some very nice additions to the overall process that we’ve added while other people were not in the office (Jason’s code elves were hard at work!). We’ve moved to VS 2005 for windows builds and have been cranking away on new and improved customer support and log analyzing tools. A lot of improvements and fixes that have been cooking for some time are going into this release and I think it represents a great deal of progress. I was finally able to get in some heavy server and network performance oriented work that I actually wrote the bulk of near launch. The changes were deep enough that they have been incubating since then before making it into an official release.

The soon to follow patch notes will do a much better job than I could of summarizing what’s coming. Moving forward the team is moving to a cross-discipline strike team approach and we’ll be delivering some great targeted features as soon as they are ready.

In some small amounts of downtime I’m doing a small amount of hacking on rubycube trying to get perspective mode to be an intuitive thing to work with and considering a move internally to fixint handles for shapes to better control lifetime events.

Other cool stuff going on:

In Progress:

Finished:

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

Many wonderful things can be done with binary trees. One brilliant usage of the binary tree was proposed by David Huffman in 1951 at MIT which has since become the foundation for much of the compression technology available today. Huffman discovered a simple way to generate a provable minimal binary encoding given a set of input symbols. It’s a deep subject, and one which I’d eventually like to spend more time getting into. For now I’ll walk through how this simple idea can be used to implement some decent compression using pure Ruby.

First of all you have your basic binary tree representation. I previously showed a simple binary tree example that demonstrates how binary trees are easily manipulated in ruby. Every binary tree node holds a value and links off to a right and left nodes that may also hold values. A leaf node is a node with dead links (left and right are both set to nil).

In the Huffman tree the leaves contain a single symbol while interior nodes summarize their sub-tree. I have simplified the idea so that all nodes wrap what is called an association list (assoc list). This is an old lisp idiom of a list containing name value pairs in the form ((name value) (name value)). To find a value in an association list you just walk the list looking at the first element of each sub-list. A reverse association list (rassoc list) takes the same form as an assoc list with the name and value pair swapped. For very small sets of data the performance of assoc lists is better than deeper structures such as a hash or tree. Ruby provides a few array APIs to deal with assoc and rassoc lists. I always store a rassoc list with the (occurance count, symbol) in a leaf and a sum of all contained lists in interior nodes. None of this information is important in understanding how Huffman encoding works but I use this concept below so I thought I should at least call it out.

class Node
    # binary tree representation
    attr_accessor :value, :left, :right
    def initialize(value=nil, left=nil, right=nil)
        @value, @left, @right = value, left, right
    end
    def leaf?
        return @left == nil && @right == nil
    end
end

By default the node is initialized to be empty with no links. A simple query method ‘leaf?’ is added for some syntactic sugar below when dealing with the tree.

The first step in building the Huffman tree is to build a set of occurrences for the data you want to encode. Some algorithms are able to this dynamically for streams of data but in this case I walk the entire input text first to find all symbols. In this implementation a symbol is a single character. Keep in mind that it is possible to use words or other unique symbols instead of single characters which could result in better compression.

def occurrences(text)
    # return an ordered array of [occurrences, character] ascending order
    occ = Hash.new(0)
    text.scan /./m do |b| occ[b] += 1 end 
    return occ.keys.map {|k| [occ[k], k]}.sort
end

The hash table occ is initialized with a default value of zero which causes all new entries to start at zero. Every character of the text is scanned and the characters are counted using the hash table. The final stage is to create an array of [count, character] entries in sorted order. Map executes the block over each key looking up the value of the key and outputting a single rassoc element per hash entry.

The final stage in building the tree is to convert the list into a tree representation. The occurrence entries are converted into leaf nodes and put into a queue in ascending order. Two entries are removed from the queue merged onto an interior node and placed onto a second queue. The interior node sums the rassoc list from both nodes that are consumed. If there are no nodes in the primary queue a node will be removed from the secondary queue. The final node remaining is the root of the tree.

def huffman(occlist)
    # build a huffman encoding binary tree from the occurrence list
    if occlist.empty? then
        puts "warning: no occurrences provided to build huffman tree"
        return nil
    end

    # create the initial queue with leaves, trees contain assoc lists
    leaves = occlist.map {|entry| Node.new([entry]) }
    interior = []
    deq = lambda {
        if (leaves.length > 0) then leaves.delete_at 0 
        else interior.delete_at 0 end
    }

    # create interior nodes
    while leaves.length + interior.length > 1
        l, r = deq.call, deq.call
        node = Node.new(l.value + r.value, l, r)
        interior << node
    end

    deq.call
end

Interior nodes are only formed in the second portion of the Huffman build function. It will only consume leaf nodes or or other interior nodes that represent the edge of the tree. In this way the tree is built bottom up and balanced.

Next up is a bit of a utility function that takes a Huffman tree and a symbol and converts it into an array of 0s and 1s that represent the binary encoding of the symbol. Walking the tree is represented by a 0 or 1 for the left and right sub-trees respectively.

def bits(ht, sym)
    # given a tree and symbol return an array of encoded bits  
    def bits_internal(ht, sym, enc)
        return enc, nil if not ht
        return enc, ht.value if ht.leaf?

        if ht.left.value.rassoc(sym) != nil
            enc << 0
            bits_internal(ht.left, sym, enc)
        else
            enc << 1
            bits_internal(ht.right, sym, enc)
        end
    end

    if ht.value.rassoc(sym) == nil
        puts "warning: no binary encoding for: '#{sym}'"
        return []
    end

    enc, value = bits_internal(ht, sym, [])
    if value[0][1] != sym 
        puts "warning: binary encoding: #{enc.inspect}, value: #{value.inspect} does not match '#{sym}'"
        return []    
    else
        return enc
    end
end

Bits makes use of the internally stored assoc lists to figure out which sub-tree should be visited. There are more efficient ways to implement this but this method is fine for example purposes. Bits() uses an internal method bitsinternal() which is implemented in a recursive style similar to visit() from the previous binary tree code. Bits does a bit of error checking on the result from bitsinternal() before returning the encoding value back to the caller.

Similar to bits_internal() above decode() will visit the tree using the binary representation in an array and choose the left or right sub-trees. Each time decode calls itself it uses a slice of the original array. If you are familiar with lisp code this method of traversal will look very familiar. When we have arrived at a leaf we know that we have found the symbol and it is returned.

def decode(ht, bits)
    if ht.leaf? 
        return ht.value[0][1]
    end

    case bits[0]
        when 0 
            decode(ht.left, bits[1..bits.length-1])
        when 1 
            decode(ht.right, bits[1..bits.length-1])
    end
end

Now for a simple test of the Huffman encoding procedures above. The standard Lorem Ipsum text will be used. The history of this randomized Latin text is very interesting, it is extracted from an early text on ethics by Cicero which was written in 45 BC.

text = <<TEXT
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed est nulla, suscipit vel, tempus sit amet, viverra sit amet, dui. Nunc ultrices, purus vulputate luctus sodales, mauris augue elementum diam, in ornare neque nisi pharetra lectus. In hac habitasse platea dictumst. Phasellus justo turpis, laoreet id, semper at, convallis a, nisi. Duis iaculis erat et mauris. Donec a arcu. Ut sed risus vel mi mollis vehicula. Aenean laoreet, lorem dapibus aliquam ultrices, ante velit vestibulum sem, vel molestie arcu elit sit amet nunc. Vivamus venenatis placerat dui. Mauris porttitor varius velit. 
TEXT

To measure the effectiveness of the compression I will sum the bits of the raw text assuming each character were to take a modern standard byte (8bits).

# build a huffman encoding tree
ht = huffman(occurances(text))

# measure the compression
bitsum = 0
for c in text.scan /./m
    bitsum += bits(ht, c).length
end

orig = text.length
new = bitsum / 8.0
printf("original %s bytes, huffman encoded: %s bytes, ratio: %.2f%%", 
orig, new, new/orig*100)

And what do we get for our efforts on this humble piece of ruby code:

original 598 bytes, huffman encoded: 374.25 bytes, ratio: 62.58%

~63% compression ratio. Not too shabby!

Click here to view the sample source code

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

Build a Binary Tree in Ruby

Building algorithms in ruby is fun and rewarding. This binary tree doesn’t balance itself but it is simple and flexible using ruby blocks for visit and insert. Traversal style can be selected optionally to visit with :inorder, :preorder or :postorder.

Here’s your basic binary tree node representation, it holds a value and connects to a left and right node:

class Node
    # binary tree representation
    attr_accessor :value, :left, :right
    def initialize(value=nil, left=nil, right=nil)
        @value, @left, @right = value, left, right
    end
end

Insert receives a value and a block which is responsible for doing the comparison. Comparison would normally be done with the Ruby <=> operator (this is the case later when the chunkybacon is inserted into the tree). The block passed to insert receives two elements and should yield a -1 for less, 1 for greater or 0 for equal. This function is implemented in terms of itself, notable for it’s lack of any balancing.

def insert(node, v, &block)
    # binary tree insert without balancing, 
    # block performs the comparison operation
    return Node.new(v) if not node
    case block[v, node.value]
        when -1 
            node.left = insert(node.left, v, &block)
        when 1 
            node.right = insert(node.right, v, &block)
    end
    return node
end

Visit receives the order that the nodes should be visited as well as a block that will act as a visitor of the stored values. This function is also implemented in terms of itself.

def visit(n, order=:preorder, &block)
    # visit nodes in a binary tree, order can be determinied
    # block performs visit action
    return false unless (n != nil)

    case order 
        when :preorder 
            yield n.value
            visit(n.left, order, &block)
            visit(n.right, order, &block)
        when :inorder
            visit(n.left, order, &block)
            yield n.value
            visit(n.right, order, &block)
        when :postorder
            visit(n.left, order, &block)
            visit(n.right, order, &block)
            yield n.value
    end
end

And here is a simple example of inserting the string ‘chunkybacon’ into the binary tree. The result of visiting this tree using :inorder traversal is the string ‘abchknouy’.

if $0 == __FILE__
    # a simple test case
    root = nil
    "chunkybacon".scan(/./m) {|c| root = insert(root, c) {|a,b| a<=>b}}
    visit(root, :inorder) {|v| print v}
end

You may like it you will see, try it, try it and leave a comment for me.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

In ruby the default way to get a name to return a value is via ruby’s lexical scoping rules. Lexical scoping rules use the way the code is written to determine what a variable name means. You can read the code and understand what a variable will mean when a certain piece of code runs. The alternative to lexical binding is dynamic binding. Dynamic binding determines the value of a variable by the process executing the code. Dynamic binding has a potential to be more confusing because code written this way could have a variety of meanings depending on how the code is executed. Old versions of lisp used dynamic binding by default. In common lisp lexical binding is the default but it is still possible to make a variable dynamically bound.

There are certain scenarios where dynamic binding is particularly useful. It allows the caller to directly control the callee without using any intermediate objects, instead only using the underlying call chain. Certain forms of generic programming become very easy with dynamic binding.

Consider the following as an illustration of implicit dynamic binding:

def print_list(a_list)
  puts a_list.join(separator or ', ')  
end

print_list([1, 2, 3]) # -> 1, 2, 3
separator = ' '
print_list([1, 2, 3]) # -> 1 2 3

The simple example above also illustrates how implicit dynamic binding in a programming language can really start to dirty up a perfectly good code base. An unfortunate misspelling would be hard to debug in such a language. Additionally various rules about encapsulation are broken along the way.

The dynamic binding style still does have it uses however, especially in a language that supports functional abstraction. In ruby it is possible to define your own function objects and pass them around easily.

my_lambda = lambda {|x| puts x + 10 }
my_lambda.call(1) # -> 11
my_lambda.call(2) # -> 12

The lambda method in Kernel#lambda returns a new Proc that wraps the code in the block ‘{}’.

In some cases it could be useful to define a dynamically bound lambda that defines actor behavior in a generic way.

def execute_all(actor_list, proc)
  actor_list.each {|actor| actor.execute(proc) }
end
execute_all(lambda {play_anim(anim_family, 'walk', speed) }

The details of the lambda are open to the interpretation of the actor at the time the code runs. I’m not of the opinion that this is the best way to write this code but it certainly wins in brevity and in being fairly generic. There are better examples of using dynamic binding in the common lisp system.

To contrast dynamic binding here is an example of lexical binding. The lambda defined here binds a_var at the point the lambda is written, not where it is run (hence lexical scoping). This create a lexical closure which closes over the definition of a_var to keep it around later. The value returned below is 1 although at the time the code runs there is a binding for a_var that changes it’s meaning to 2.

def foo(p)
   a_var = 2
   puts p.call
end
a_var = 1
foo(lambda { a_var }) # -> 1

If ruby used dynamic binding by default the output of the code snipped above would be 2. To resolve a dynamically bound variable you walk up the chain of current activation records to find the nearest variable binding. In ruby the lexical variable binding captures a lot, including the current ’self’, block iterator, and locals.

Now that I’ve covered all that I can talk about ruby tools for working with the bindings and different ways to program with a more dynamic mode.

In ruby it is possible to access the binding from code. The kernel method binding offers the caller access to an opaque Binding object. Currently the only way to use this binding object that I have found is via eval().

def foo()
  a = 1
  return binding
end

b = foo()
eval('puts a', b) # -> 1

The binding is manually captured here and passed into eval. This is a form of explicit dynamic binding. The only drawback of this method is that it doesn’t work for forms that have already been evaluated.

Explicit run-time variable binding is a pretty common software pattern. The alternative that is often used in C++ or Java is to create a special context object which is passed as a parameter to a method. The context is a way of explicitly controlling the binding. You create a custom mapping object (a hash for example) and pass it around to create your own variable binding. Here’s an example:

def foo(ctx, proc)
    puts proc.call() # -> 1
    ctx[:x] = 2
    puts proc.call() # -> 2
end

ctx = {:x=>1}
foo(ctx, lambda {|ctx| ctx[:x] })

Wouldn’t it be nice if we could encapsulate this pattern without requiring the extra parameter, dictionary mapping and extra indirection of having to make all variable access through the mapping?

I haven’t looked at the C code changes that would be required to ruby to do this but I think it’s possible to roll this pattern of coding directly into the ruby built-in library.

The additions are Binding#from_hash(aHash), Proc#call_with_binding(aBinding).

def let(k, &block)
  block.call_with_binding(Binding.from_hash(k))
end

let('a_var'=>1) {
  puts a_var
} # -> 1

dynamic_bound = lambda {
  puts a_var
}
a_var = 1
dynamic_bound.call_with_binding(binding) # -> 1

a_var = 2
dynamic_bound.call_with_binding(binding) # -> 2

The above code is a hypothetical approach. One that might be interesting to implement. There is one more alternative to lexical binding in ruby that I discovered after I had initially written this post. It relies directly or indirectly on the usage of instance_eval. Here’s a simple example:

class Foo
  def initialize(a) @a = a end
end

f = Foo.new(1)
f.class.send(:define_method, :foo, lambda { puts @a })
f.foo # -> 1

f2 = Foo.new(2)
f2.foo # -> 2

The method :define_method defines the proc in terms of Foo. The @a binds to the meaning of @a in the context of an instance of Foo.

A less permanent way to do this is to use instance_eval directly:

f.instance_eval { @a = @a + 10 }
Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

I’m working on some ruby code today on a cleanly installed vim. I decided to improve my editing experience a bit and found some a couple enhancements that work quite nice together.

Evaluate ruby with the press of a button

You can see the source of this tip from the vim wiki. I find the last bit of code the best of them:

function! Ruby_eval_vsplit() range
  let src = tempname()
  let dst = "Ruby Output"
  " put current buffer's content in a temp file
  silent execute ": " . a:firstline . "," . a:lastline . "w " . src
  " open the preview window
  silent execute ":pedit! " . dst
  " change to preview window
  wincmd P
  " set options
  setlocal buftype=nofile
  setlocal noswapfile
  setlocal syntax=none
  setlocal bufhidden=delete
  " replace current buffer with ruby's output
  silent execute ":%! ruby " . src . " 2>&1 "
  " change back to the source buffer
  wincmd p
endfunction

vmap <silent> <F7> :call Ruby_eval_vsplit()<cr>
nmap <silent> <F7> mzggVG<F7>`z
imap <silent> <F7> <ESC><F7>a
map <silent> <S-F7> <C-W>l:bw<cr>
imap <silent> <S-F7> <ESC><S-F7>a

Select some ruby code and hit F7 or hit F7 to evaluate the entire buffer. A new split is automatically opened or it uses an existing split if one is available.

Create a usable scratch buffer

Now if you combine that with the scratch.vim plugin you have a nice little 1-2 punch combination of ruby prototyping bliss. Nub tip: download scratch.vim put into $VIMDIR\vimfiles\plugins\ restart your editor and type :Scratch then type :set ft=ruby to get ruby syntax highlighting in the scratch buffer.

I may be wrong but I think this stuff comes with the emacs ruby mode for free (scratch buffer is a built-in emacs feature).

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

Laid-back New Years

Somehow I managed to hurt my back before new years and so I have been laid up in bed for three days. I am extremely fortunate to have a good friend (and neighbor) who is a chiropractor and it seems that I have a ‘bulging disk’. No idea really what caused it but it hurts like crazy and when I am able to stand my torso leans to the side. So far I’m making a pretty good recovery and all I have to keep myself occupied is my laptop and book collection.

Playing Tabula Rasa

I leveled from 15 to 24 in Tabula Rasa, collected a mountain of feedback on various aspects of the game that need improvement. I spent a lot of time with the auction system and did all of the Targets of Opportunity quests so that I now have 100% completed wilderness and divide with one instance left to complete palisades. I never had so much time to play the game while working on it really, contrary to the popular belief that game programmers play games all day. My concerns are all in the low-level details most of the time and I had so much systems code to fix I was low on free time. You wouldn’t expect your German car specialist to be driving your BMW around all day now would you? It further cements in my mind the need to keep my own games very small so that I can work on them and play them completely. While playing I also had many epiphanies about what an MMO could be. I think the best part of playing though was meeting all the passionate players of TR and really listening to what they want out of the game and what their frustrations are.

Reading up on CL

Some people close to me know that I have been studying common lisp a lot lately. I spent a lot of time with the ray tracing code from ANSI Common Lisp by Paul Graham which is really a nice introduction to numerical computation. I took the ray tracer from the book and attempted to optimize it on my Core2 laptop running ubuntu 7.1. I ran it in CLISP which result in a 12 second run time for 100,000 samples. Compiling and running in CLISP cut that down to 1.2 seconds. Converting to SBCL and compiling brought that time down to 0.2 seconds. I couldn’t get any faster than this so I tried getting SBCL to stop boxing all the floating point math. Basically all floating point values are stored on the heap and the math uses generic operations which has to do a type check to select the correct (high-level) math routine. The next step of performance really needs to use direct argument passing and floating point math which is actually more complex than I realized. This little bit of research took me down the road of reading how Python (the compiler not the language) works. This dovetails with some of my interest in compilers, assembly and vector instructions so my current pet project for CL is to write a toy vector compiler using lisp as the language and implementation.

Working on Python

I spent some time working on my log parser/web viewer for the TR server logs. I added some interesting features for the back end implemented (free text index, server:minute index, error:function index) to allow effective navigation of large amounts of log data. Currently using shelve for persistence and a simplified in memory python database for querying. I’m also using web.py as the serving engine.

XNA

I downloaded XNA GSE 2.0 and the devkit to my new laptop but then started remembering how much I actually have grown to detest XNA and the stinky platform pigeon hole that it forces developers into. I have a blog rant queued up for more than a year about that.. I should probably publish that.

General Research

Zed Shaw published a strong position rant on the ruby on rails community

His site led me to read up on Ragel, Kwangju Uprising and NLP

Elements of Style is online

I’m enjoying this talk on Behavior Trees

Anyways, way too much time on my hands I don’t like being stuck in bed but it certainly gives me a lot more sympathy for those that are.

Here’s to an excellent year gone by and a new year full of promise.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

Using autoreload with web.py

I tried using web.py today for a small project at work. The basic idea of the project is that a simple python script converts a tree of log files into a database file. The same script can be run to view, search and slice any previously created database file. I’m planning on pulling out some of the small bits to show some example python code. For today I’ll focus on a problem I ran into with web.py and how I solved it.

Web.py on the surface is a very simple and slick python web framework. I’m using version .22 which is the latest stable release. The documentation is a bit hard to parse, it’s really just a dump of the comments from the code. Really you’re better off just going to read the code which itself is hackish.

In web.py examples you start so:

import web

class index:
    def GET(self):
        print 'hello!'

urls = ('/', index)
web.run(urls, globals())

This starts up the built-in web server on port 8080 and you can see ‘hello!’ in your browser right away. Pretty slick.

After working with it for awhile you’ll soon be sick of restarting the server and the documentation describes the auto-reload feature so:

web.run(urls, globals(), web.reloader)

All ‘middleware’ goes into the *rest parameter of the run() method. Using the web.reloader module doesn’t work right away like this though.

First on a design level I should point out a few problems. Instead of using web.reloader in an abstract way the web.run() method is specialized for this particular module and changes it’s internal behavior when you pass it in. Additionally, you cannot use the same model of calling web.run() with and with-out web.reloader. This seems like a long standing problem in the request.py file. I looked at a recent development snapshot and it’s still the same way.

Personally, I think that auto-reloading of web request modules should be a built-in feature anyways as it is a core element of a web programming framework even one as light weight as this. Perhaps other containers implement it for you automatically so this feature has not gotten the love it needs.

At first I didn’t understand how the internals worked correctly so to get around this I rolled a very simple auto-reload functionality into my web viewer module. The concept was so simple and frankly I was frustrated after looking at some web.py internals:

def _OnImport():
  """Execute on initial import of module"""
  import sys, os
  global g_mtime
  g_mtime = os.stat(__file__).st_mtime
_OnImport()

def _AutoReload():
  """Call to reload this module as needed"""
  import sys, os
  global g_mtime
  fn = __file__
  if __file__.endswith('.pyc'): 
    fn = __file__[:-1]
  mtime = os.stat(fn).st_mtime
  if mtime > g_mtime:
    reload(sys.modules[__name__])
    g_mtime = mtime
    return True
  return False

class Request(object):
  def __init__(self):
    self.reloaded = _AutoReload()

class Main(Request):
  def GET(self):
    print 'hello! (reloaded: %s)' % self.reloaded

def Start():
  import web
  urls = ('/', 'Main')
  web.run(urls, globals())

The style is a bit non-python idiomatic, it’s roughly our coding style at work.

Then I ran into a problem: using my method there was no way to add new url mappings to web.py while it was running. Then I finally realized what the correct (undocumented) way of using web.reloader is:

urls = ('/', 'Main')
def Start():
  import web
  web.run('urls', globals())

The key is moving urls into a global of the module and specifying the name of the global variable instead of it’s value. All this so that the following special-case code in request.py works as intended:

def webpyfunc(inp, fvars, autoreload=False):
  #...
  mod = __import__(modname(), None, None, [""])
  #@@probably should replace this with some inspect magic
  name = utils.dictfind(fvars, inp)
  func = lambda: handle(getattr(mod, name), mod)
  #...

The utils.dictfind() method returns the tuple mapping from the module dictionary and passes it to handle() in the lambda. Every time the lambda is invoked it does the lookup of the tuple so that it can change on the fly.

In the end this works much better than my home grown autoloader but the usage of it took me way to long to get right.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Technorati
  • Reddit
  • Digg
  • del.icio.us
  • StumbleUpon
  • DZone
  • ThisNext

Related posts:

« Prev - Next »