Last active
August 29, 2015 14:23
-
-
Save kana-sama/615a05d68fa8fa142267 to your computer and use it in GitHub Desktop.
This file contains 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
# Я только-только начал изучать Ruby, мне очень понравилось то, что | |
# в языке очень много сахара. Но при этом там нет сахара для быстрых | |
# конструкторов, которые есть даже в C++ и CS | |
# constructor: (@name, @age) -> | |
class PersonOld | |
def initialize(name, age) | |
# вот эти строки меня и бесят | |
@name = name | |
@age = age | |
end | |
def to_s | |
"My name is #{@name} and I am #{@age} years old." | |
end | |
end | |
# Поэтому я решил написать метод (я так понял, это называется объявление), | |
# который создает такие конструкторы | |
class Class | |
private | |
class ArgumentPair < Array | |
def name | |
"ArgumentPair" | |
end | |
end | |
def initializer_for(*attrs, **attrs_hash, &after_initialize) | |
define_method :initialize do |*values| | |
unless attrs_hash.nil? | |
attrs += attrs_hash.to_a.map { |a| ArgumentPair.new(a) } | |
end | |
Array(attrs).zip(Array(values)).each.with_index do |(a, v), i| | |
attr, val = a, v | |
if a.is_a? ArgumentPair | |
attr = attrs[i][0] | |
val = attrs[i][1] if val.nil? | |
end | |
instance_variable_set("@#{attr.to_s}", val.to_s) | |
end | |
instance_eval(&after_initialize) if block_given? | |
end | |
end | |
end | |
# Теперь можно писать так | |
class PersonExample | |
initializer_for :name, "age" | |
def to_s | |
"My name is #{@name} and I am #{@age} years old." | |
end | |
end | |
# Добавил несколько фич: значения по умолчанию и код, который выполнится | |
# в конце конструктора | |
class Person | |
initializer_for :name, age: 17 do | |
@name.capitalize! | |
end | |
def to_s | |
"My name is #{@name} and I am #{@age} years old." | |
end | |
end | |
# В итоге имеем | |
me = Person.new("andrew") | |
puts me | |
# => Hello, my name is Andrew and I am 17 years old! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment