Skip to content

Instantly share code, notes, and snippets.

@colinta
Created May 7, 2013 15:49
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colinta/5533684 to your computer and use it in GitHub Desktop.
Save colinta/5533684 to your computer and use it in GitHub Desktop.
Here's what I mean when I say "ReactiveCocoa is just a fancy word for: 'DSL'"

I don't want anyone to think that I am not a big fan of ReactiveCocoa. I'm a HUGE FAN of it!

But look how LONG it took for something like this to come about. Cocoa is an OLD OLD system, and even though KVO/KVC wasn't there at the birth, it has been there at least a decade. I pretty much gave up on Obj-C in favor of RubyMotion, and look at our landscape: Futuristic, ProMotion, Formotion, Geomotion, Elevate, Teacup - all of these projects bring expressiveness to Cocoa, and RubyMotion is barely a year old.

So what I meant to say is that Obj-C suffers from a lack of expressiveness - this has nothing to do with ReactiveCocoa, that's just my example. To illustrate my point, I will translate the first example of the ReactiveCocoa README. I encourage you to read the ReactiveCocoa source and try and consolidate all the code that is used to handle this function. I will include all of the Ruby code that is necessary for my translation to work.

I do have one qualm with ReactiveCocoa: the names. I'm going to translate the comments into (what I hope is equivalent) plain English.

Objective-C
// When self.username changes, log the new name to the console.
//
// RACAble(self.username) creates a new RACSignal that sends a new value
// whenever the username changes. -subscribeNext: will execute the block
// whenever the signal sends a value.
[RACAble(self.username) subscribeNext:^(NSString *newName) {
    NSLog(@"%@", newName);
}];
RubyMotion
# When self.username changes, log the new name to the console
#
# self.kvc(:username) creates an object you can use to observe the value of `self.username`
self.kvc(:username).observe do |new_name|
  puts new_name
end

# here's the code to add that feature:

# add the `kvc` method to all objects
class Object
  def kvc(property)
    KVC.new(self, property)
  end
end

# add observing to Procs
class Proc
  def observeValueForKeyPath(path, ofObject: target, change: change, context: ctx)
    self.call(change['new'])
  end
end

class KVC
  attr :target
  attr :key_path

  def initialize(target, key_path)
    @target = target
    @key_path = key_path.to_s
  end

  def observe(&block)
    self.target.addObserver(block, forKeyPath: self.key_path.to_s, options: NSKeyValueObservingOptionNew, context: nil)
  end

end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment