Last active
December 14, 2021 18:32
-
-
Save DmitryTsepelev/ab1797e7d00b484973615ba1782e0e36 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MyAttrAccessor | |
def my_attr_accessor(attr_name) | |
my_attr_reader(attr_name) | |
my_attr_writer(attr_name) | |
end | |
def my_attr_reader(attr_name) | |
instance_variable_name = attr_to_variable_name(attr_name) | |
define_method(attr_name) do | |
instance_variable_get(instance_variable_name) | |
end | |
end | |
def my_attr_writer(attr_name) | |
instance_variable_name = attr_to_variable_name(attr_name) | |
define_method("#{attr_name}=") do |value| | |
instance_variable_set(instance_variable_name, value) | |
end | |
end | |
private | |
def attr_to_variable_name(attr_name) | |
"@#{attr_name}" | |
end | |
end | |
Object.extend(MyAttrAccessor) | |
class User | |
my_attr_accessor :email | |
def initialize(email: nil) | |
@email = email | |
end | |
end | |
user = User.new | |
user.email = '[email protected]' | |
puts user.email # => [email protected] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MyAttrAccessor | |
def self.[](attr_name) | |
Module.new do | |
instance_variable_name = "@#{attr_name}" | |
define_method(attr_name) do | |
instance_variable_get(instance_variable_name) | |
end | |
define_method("#{attr_name}=") do |value| | |
instance_variable_set(instance_variable_name, value) | |
end | |
end | |
end | |
end | |
class User | |
include MyAttrAccessor[:email] | |
def initialize(email: nil) | |
@email = email | |
end | |
end | |
user = User.new | |
user.email = '[email protected]' | |
puts user.email # => [email protected] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Builder | |
def get(path, **args) | |
routes[['get', path]] = args | |
end | |
def post(path, **args) | |
routes[['post', path]] = args | |
end | |
def routes | |
@routes ||= {} | |
end | |
end | |
class Router | |
NOT_FOUND = 'NOT_FOUND' | |
def self.draw | |
builder = Builder.new | |
yield(builder) | |
new(builder) | |
end | |
def initialize(builder) | |
@builder = builder | |
end | |
def route(method_and_path) | |
method, path = method_and_path.split(' ') | |
@builder.routes[[method.downcase, path]] || NOT_FOUND | |
end | |
end | |
router = Router.draw do |builder| | |
builder.get '/users', controller: :users, action: :index | |
builder.post '/users', controller: :users, action: :create | |
end | |
puts router.route('GET /users') # => {:controller=>:users, :action=>:index} | |
puts router.route('POST /users') # => {:controller=>:users, :action=>:create} | |
puts router.route('GET /orders') # => NOT_FOUND |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Router | |
NOT_FOUND = 'NOT_FOUND' | |
def self.draw(&block) | |
new.tap { |router| router.instance_eval(&block) } | |
end | |
def route(method_and_path) | |
method, path = method_and_path.split(' ') | |
routes[[method.downcase, path]] || NOT_FOUND | |
end | |
def get(path, **args) | |
routes[['get', path]] = args | |
end | |
def post(path, **args) | |
routes[['post', path]] = args | |
end | |
def routes | |
@routes ||= {} | |
end | |
end | |
router = Router.draw do | |
get '/users', controller: :users, action: :index | |
post '/users', controller: :users, action: :create | |
end | |
puts router.route('GET /users') # => {:controller=>:users, :action=>:index} | |
puts router.route('POST /users') # => {:controller=>:users, :action=>:create} | |
puts router.route('GET /orders') # => NOT_FOUND |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Router | |
class << self | |
def draw(&block) | |
new.tap { |router| router.instance_eval(&block) } | |
end | |
def generate_route_methods(*method_names) | |
method_names.each do |method_name| | |
define_method(method_name) do |path, **args| | |
routes[[method_name, path]] = args | |
end | |
end | |
end | |
end | |
generate_route_methods :get, :post, :patch, :delete | |
NOT_FOUND = 'NOT_FOUND' | |
def route(method_and_path) | |
method, path = method_and_path.split(' ') | |
routes[[method.downcase, path]] || NOT_FOUND | |
end | |
def routes | |
@routes ||= {} | |
end | |
end | |
router = Router.draw do | |
get '/users', controller: :users, action: :index | |
post '/users', controller: :users, action: :create | |
end | |
puts router.route('GET /users') # => {:controller=>:users, :action=>:index} | |
puts router.route('POST /users') # => {:controller=>:users, :action=>:create} | |
puts router.route('GET /orders') # => NOT_FOUND |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DB | |
def self.instance | |
@instance ||= new | |
end | |
def users | |
@users ||= {} | |
end | |
end | |
module CoolRecord | |
def self.included(base) | |
base.extend(ClassMethods) | |
end | |
def save | |
record_id = | |
if new_record? | |
self.id = (DB.instance.users.map(&:id).max || 0) + 1 | |
else | |
id | |
end | |
self.class.table[record_id] = { id: record_id, email: email, name: name } | |
end | |
def new_record? | |
id.nil? | |
end | |
module ClassMethods | |
def where(conditions) | |
table.values | |
.select { |attrs| conditions.all? { |(attr_name, value)| attrs[attr_name] == value } } | |
.map { |attrs| self.new(**attrs) } | |
end | |
def find_by(conditions) | |
where(conditions).first | |
end | |
def table | |
DB.instance.public_send(table_name) | |
end | |
private | |
def table_name | |
"#{self.name.downcase}s" | |
end | |
end | |
end | |
class User | |
include CoolRecord | |
attr_accessor :id, :email, :name | |
def initialize(id: nil, email: nil, name: nil) | |
@id = id | |
@email = email | |
@name = name | |
end | |
end | |
user = User.new(email: '[email protected]', name: 'John') | |
user.save | |
puts User.where(name: 'John').inspect # => [#<User:0x00007fa5f385c2f8 @id=1, @email="[email protected]", @name="John">] | |
puts User.find_by(name: 'John').inspect # => #<User:0x00007fa5f3834398 @id=1, @email="[email protected]", @name="John"> | |
puts User.where(name: 'Jane').inspect # => [] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module MyAttrAccessor | |
def my_attr_accessor(attr_name) | |
class_eval <<~TEMPLATE | |
def #{attr_name} | |
@#{attr_name} | |
end | |
def #{attr_name}=value | |
@#{attr_name} = value | |
end | |
TEMPLATE | |
end | |
end | |
Object.extend(MyAttrAccessor) | |
class User | |
my_attr_accessor :email | |
def initialize(email: nil) | |
@email = email | |
end | |
end | |
user = User.new | |
user.email = '[email protected]' | |
puts user.email # => [email protected] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment