Created
November 18, 2014 10:51
-
-
Save shikhalev/5f19659a7ed82ce83c58 to your computer and use it in GitHub Desktop.
Для статьи «Метапрограммирование в Ruby: разбор примера»
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
# encoding: utf-8 | |
require './prop00' | |
class Alpha | |
property :alpha, :beta | |
attr_accessor :gamma | |
end | |
a = Alpha.new | |
a.alpha = 1 | |
a.beta = 2 | |
a.gamma = 3 | |
p [a.alpha, a.beta, a.gamma] | |
p a | |
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
# encoding: utf-8 | |
require './prop01' | |
class Alpha | |
property :alpha, default: 100 | |
property :beta, default_proc: proc { |o| o.class.name } | |
property :gamma, default_proc: :class | |
end | |
a = Alpha.new | |
p [a.alpha, a.beta, a.gamma] | |
p a | |
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
# encoding: utf-8 | |
require './prop02' | |
class Alpha | |
property :alpha | |
property :beta do |obj, prop, value| | |
p [obj, prop, value] | |
end | |
end | |
a = Alpha.new | |
a.alpha = 100 | |
a.beta = 200 |
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
# encoding: utf-8 | |
require './prop03' | |
class Alpha | |
property :alpha, filter: Integer | |
property :beta, filter: proc { |x| Integer === x && x > 0 }, | |
on_invalid: StandardError | |
end | |
a = Alpha.new | |
a.alpha = 11 | |
a.beta = 2 | |
p a | |
a.alpha = "String" | |
p a | |
a.beta = -1 | |
p a |
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
# encoding: utf-8 | |
class Module | |
private | |
def prop name | |
varnm = "@#{name}" | |
getnm = name | |
setnm = "#{name}=" | |
define_method getnm do | |
instance_variable_get varnm | |
end | |
define_method setnm do |value| | |
instance_variable_set varnm, value | |
end | |
end | |
def property *names | |
names.each do |nm| | |
prop nm | |
end | |
end | |
end |
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
# encoding: utf-8 | |
class Module | |
private | |
def prop name, default: nil, default_proc: nil | |
varnm = "@#{name}" | |
getnm = name | |
setnm = "#{name}=" | |
define_method getnm do | |
if ! instance_variable_defined?(varnm) | |
if default_proc | |
instance_variable_set varnm, | |
default_proc.to_proc.call(self) | |
else | |
instance_variable_set varnm, default | |
end | |
end | |
instance_variable_get varnm | |
end | |
define_method setnm do |value| | |
instance_variable_set varnm, value | |
end | |
end | |
def property *names, default: nil, default_proc: nil | |
names.each do |nm| | |
prop nm, default: default, default_proc: default_proc | |
end | |
end | |
end | |
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
# encoding: utf-8 | |
class Module | |
private | |
def prop name, default: nil, default_proc: nil, &block | |
varnm = "@#{name}" | |
getnm = name | |
setnm = "#{name}=" | |
define_method getnm do | |
if ! instance_variable_defined?(varnm) | |
if default_proc | |
instance_variable_set varnm, | |
default_proc.to_proc.call(self) | |
else | |
instance_variable_set varnm, default | |
end | |
end | |
instance_variable_get varnm | |
end | |
define_method setnm do |value| | |
instance_variable_set varnm, value | |
if block | |
block.call self, name, value | |
end | |
end | |
end | |
def property *names, default: nil, default_proc: nil, &block | |
names.each do |nm| | |
prop nm, default: default, default_proc: default_proc, &block | |
end | |
end | |
end | |
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
# encoding: utf-8 | |
class Module | |
private | |
def prop name, default: nil, default_proc: nil, filter: nil, on_invalid: nil, | |
&block | |
varnm = "@#{name}" | |
getnm = name | |
setnm = "#{name}=" | |
if !(on_invalid == nil || | |
(Class === on_invalid && on_invalid <= Exception) || Proc === on_invalid) | |
raise TypeError, | |
"Invalid type of 'on_invalid' argument: #{on_invalid.class}", caller | |
end | |
define_method getnm do | |
if ! instance_variable_defined?(varnm) | |
if default_proc | |
instance_variable_set varnm, | |
default_proc.to_proc.call(self) | |
else | |
instance_variable_set varnm, default | |
end | |
end | |
instance_variable_get varnm | |
end | |
define_method setnm do |value| | |
if filter && !(filter === value) | |
if Class === on_invalid && on_invalid <= Exception | |
raise on_invalid, | |
"Invalid property (#{name}) value: #{value.inspect}!", caller | |
elsif Proc === on_invalid | |
on_invalid.call self, name, value | |
end | |
else | |
instance_variable_set varnm, value | |
if block | |
block.call self, name, value | |
end | |
end | |
end | |
end | |
def property *names, default: nil, default_proc: nil, filter: nil, | |
on_invalid: nil, &block | |
names.each do |nm| | |
prop nm, default: default, default_proc: default_proc, filter: filter, | |
on_invalid: on_invalid, &block | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment