Skip to content

Instantly share code, notes, and snippets.

@d4rky-pl
Last active April 24, 2017 22:13
Show Gist options
  • Save d4rky-pl/7667c1ca9249c894cb9a4025b79479f5 to your computer and use it in GitHub Desktop.
Save d4rky-pl/7667c1ca9249c894cb9a4025b79479f5 to your computer and use it in GitHub Desktop.
mobx-ruby
require 'mobx'
Mobx.init
class Session
extend Mobx::Extension
observable :user
observable :company
end
session = Session.new
include Mobx::Extension
autorun do
puts "User: #{session.user}"
end
reaction -> { session.company } do
puts "Company: #{session.company}"
end
session.user = "Abc"
session.company = "Blah"
action do
session.user = "Abc"
session.user = "Ghi"
session.user = "Jkl"
session.company = "Def"
end
# $ ruby mobx-ruby.rb
# User:
# User: Abc
# Company: Blah
# User: Jkl
# Company: Def
module Mobx
class Autorun
def initialize(block)
@block = block
end
def call
@block.call
end
end
end
module Mobx
module Extension
def autorun(&block)
Thread.current['mobx-autorun'] << Mobx::Autorun.new(block)
block.call
Thread.current['mobx-autorun'].pop
end
def reaction(lambda, &block)
Thread.current['mobx-autorun'] << Mobx::Autorun.new(block)
lambda.call
Thread.current['mobx-autorun'].pop
end
def action(&block)
Mobx::Transaction.new(block).call
end
def observable(attr_name, value=nil)
define_method(attr_name) do
@observables ||= {}
@observables[attr_name] ||= Mobx::Observable.new(value)
@observables[attr_name].get
end
define_method("#{attr_name}=") do |value|
@observables ||= {}
if @observables.has_key?(attr_name)
@observables[attr_name].set(value)
else
@observables[attr_name] = Mobx::Observable.new(value)
end
end
end
end
end
require 'mobx/observable'
require 'mobx/autorun'
require 'mobx/transaction'
require 'mobx/extension'
module Mobx
def init
Thread.current['mobx-autorun'] = []
end
end
module Mobx
class Observable
def initialize(value)
@value = value
@observers = []
end
def get
@observers += Thread.current['mobx-autorun'] if Thread.current['mobx-autorun']
@value
end
def set(value)
@value = value
if Thread.current['mobx-transaction']
Thread.current['mobx-transaction'].schedule(@observers)
else
@observers.each { |observer| observer.call }
end
@value
end
end
end
module Mobx
class Transaction
def initialize(block)
@block = block
@scheduled = []
end
def call
if Thread.current['mobx-transaction']
@block.call
else
Thread.current['mobx-transaction'] = self
@block.call
Thread.current['mobx-transaction'] = nil
@scheduled.each { |observer| observer.call }
@scheduled = []
end
end
def schedule(observers)
@scheduled = (@scheduled + observers).uniq
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment