Skip to content

Instantly share code, notes, and snippets.

@matsumonkie
Created June 4, 2014 22:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matsumonkie/52e0b21a034b02b18e6c to your computer and use it in GitHub Desktop.
Save matsumonkie/52e0b21a034b02b18e6c to your computer and use it in GitHub Desktop.
ruby - virtual proxy pattern
class VirtualProxy < BasicObject
def initialize(&loader)
@loader = loader
@object = nil
end
def method_missing(name, *args, &block)
__load__
@object.public_send(name, *args, &block)
end
def inspect
"VirtualProxy(#{@object ? @object.inspect : ''})"
end
def __object__
@object
end
def __load__
@object ||= @loader.call
end
end
#----------------------------------------------------------------------
# MODEL
#----------------------------------------------------------------------
class Car
attr_accessor :name, :price, :wheels
def initialize(name, price, wheels = nil)
@name = name
@price = price
@wheels = wheels
end
end
class Wheels
attr_reader :brand
def initialize(brand)
@brand = brand
end
end
#----------------------------------------------------------------------
# MAPPER
#----------------------------------------------------------------------
class CarMapper
DATA_SRC = {
3 => {
:name => 'Ferrari',
:price => 100_000,
:wheels_id => 42,
}
}
def wheels_mapper
WheelsMapper.new
end
def find(id)
data_src = DATA_SRC[id]
car = Car.new(data_src[:name], data_src[:price])
car.wheels = VirtualProxy.new {
# reset wheels attribute, so that it type is correct
car.wheels = wheels_mapper.find(data_src[:wheels_id])
}
car
end
end
class WheelsMapper
DATA_SRC = {
42 => {
:brand => 'Dunlop'
}
}
def find(id)
data_src = DATA_SRC[id]
Wheels.new(data_src[:brand])
end
end
def main
car = CarMapper.new.find 3
puts "name: #{car.name}", "price: #{car.price}$"
puts car.wheels.inspect # VirtualProxy()
puts car.wheels.__object__ # nil
puts car.wheels.brand # 'Dunlop'
end
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment