Skip to content

Instantly share code, notes, and snippets.

@bakkdoor
Created January 25, 2012 01:35
Show Gist options
  • Save bakkdoor/1674052 to your computer and use it in GitHub Desktop.
Save bakkdoor/1674052 to your computer and use it in GitHub Desktop.
Objective-C inspired Key-Value Observing in Fancy
class KVO {
class ClassMethods {
def define_slot_writer: slotname {
define_method: "#{slotname}:" with: |val| {
old_val = get_slot: slotname
set_slot: slotname value: val
match val {
case old_val -> nil # do nothing if no change
case _ ->
if: (__kvo_observers__[slotname to_sym]) then: @{ each: @{ call: [val] } }
}
}
}
}
def KVO included: class {
class extend: ClassMethods
}
def __kvo_observers__ {
{ @__kvo_observers__ = <[]> } unless: @__kvo_observers__
@__kvo_observers__
}
def observe: slotname with: block {
slotname = slotname to_sym
if: (__kvo_observers__[slotname]) then: |set| {
set << block
} else: {
__kvo_observers__[slotname]: $ Set new: [block]
}
}
}
# test
class Person {
include: KVO
read_write_slots: ('name, 'age, 'city)
}
p = Person new tap: @{
name: "Chris"
age: 24
city: "Osnabrück"
}
p observe: 'name with: @{ println }
p observe: 'city with: @{ println }
p name: "Hello" # prints "Hello"
p age: 25 # doesn't do anything, since no observer block registered
p city: "Woot Town" # prints 25
p name: "Hello" # set to same value, won't do anything
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment