returns a table with the properties in the passed table

pt = PropertyTable foo:
  get: (t) -> t.value
  set: (t, v) -> t.value = v

assert.is_nil = 'hello'
assert.equal, 'hello'

non-property key accesses return nil by default

assert.is_nil PropertyTable({}).foo

non properties can be accessed in the normal fashion

pt = PropertyTable {
    get: -> 'foo'
  bar: -> 'bar'
  frob: 'frob'

assert.equal, 'foo'
assert.equal pt.frob, 'frob'
assert.equal!, 'bar'

pt.frob = 'froz'
assert.equal pt.frob, 'froz'

writing to a non-property key sets the value

t = PropertyTable {} = 'bar'
assert.equal, 'bar'

writing to a read-only property raises an error

assert.error -> PropertyTable(foo: get: -> 'bar').foo = 'frob'