Skip to content

Instantly share code, notes, and snippets.

@diogotito
Created March 5, 2023 18:44
Show Gist options
  • Save diogotito/729ff0622d4bc25d294834232f47f279 to your computer and use it in GitHub Desktop.
Save diogotito/729ff0622d4bc25d294834232f47f279 to your computer and use it in GitHub Desktop.
My first solution for the Metakoans (https://rubyquiz.com/quiz67.html)
require 'set'
class Module
def attribute(a, &block)
(attr_name, attr_default) = if a.is_a? Hash
name, value = a.first
[name, -> { value }]
elsif block_given?
[a.to_s, block]
else
[a.to_s, -> { nil }]
end
class_eval do
#-----------------------------------------------------------------------
# Getter
#-----------------------------------------------------------------------
define_method(attr_name) do
iv_get = instance_variable_get(:"@#{attr_name}")
flag = instance_variable_get(:"@__#{attr_name}_defined")
(iv_get.nil? && flag.nil?) ? instance_exec(&attr_default) : iv_get
end
#-----------------------------------------------------------------------
# Setter (=)
#-----------------------------------------------------------------------
define_method(:"#{attr_name}=") do |v|
instance_variable_set(:"@#{attr_name}", v)
instance_variable_set(:"@__#{attr_name}_defined", !v.nil?)
end
#-----------------------------------------------------------------------
# Query (?)
#-----------------------------------------------------------------------
define_method(:"#{attr_name}?") do
flag = instance_variable_get(:"@__#{attr_name}_defined")
(flag.nil?) ? (!instance_exec(&attr_default).nil?) : flag
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment