class Module
Attributes
Public Instance Methods
# File lib/mumukit/core/modulability.rb, line 22 def as_module self end
# File lib/mumukit/core/modulability.rb, line 26 def as_module_name name end
# File lib/mumukit/core/variability.rb, line 14 def as_variable_name name.as_variable_name end
# File lib/mumukit/core/module.rb, line 111 def breaches_contract? !contract_breaches.empty? end
Caches an accessor, using the idiom `@__foo__ ||= foo`. For example, the following code:
“` def foo
@__foo__ ||= #...implementation...
end “`
Can be turned into:
“` def foo
#...implementation...
end
cache_accessor
:foo “`
# File lib/mumukit/core/module.rb, line 86 def cache_accessor(*selectors) revamp(*selectors, selector_transformer: proc { |it| "@__#{it}__".to_sym }) do |attr_name, this, hyper| this.instance_variable_get(attr_name) || this.instance_variable_set(attr_name, hyper.call) end end
# File lib/mumukit/core/module.rb, line 97 def contract @contract ||= [] end
# File lib/mumukit/core/module.rb, line 115 def contract_breaches full_contract.reject { |it| method_defined? it } end
# File lib/mumukit/core/module.rb, line 107 def full_contract ancestors.flat_map(&:contract).uniq end
# File lib/mumukit/core/module.rb, line 103 def implements(*selectors) self.contract += selectors end
Object#like?
# File lib/mumukit/core/likeability.rb, line 8 def like?(other) super || to_s.underscore == other.to_s end
Redefines a previous definition of the given method. It takes a block with the original arguments and the `hyper` reference to the original definition
# File lib/mumukit/core/module.rb, line 12 def patch(selector, &block) revamp selector do |_, this, *args, hyper| this.instance_exec(*args, hyper, &block) end end
# File lib/mumukit/core/module.rb, line 2 def required(name, message=nil) message ||= "You need to implement method #{name}" define_method name do |*| raise message end end
`revamp` is a `patch` generalization that accepts multiple selectors and takes a more general callback, like the following:
“` revamp :foo, :bar do |selector, this, *args, hyper|
puts "sending #{selector} to #{this}..." result = hyper.call(*args) puts "done. result is #{result}" result
end “`
`revamp` should be preferred to `patch` when more control or performance is required
# File lib/mumukit/core/module.rb, line 33 def revamp(*selectors, selector_transformer: nil, &block) selectors.each do |selector| method_proc = instance_method selector selector_transform = selector_transformer ? selector_transformer.call(selector) : selector define_method selector do |*args| block.call(selector_transform, self, *args, method_proc.bind(self)) end end end
Revamps an accessor. This method is similar to `revamp`, but:
* assumes a 0 arguments array * takes the accessor's original result instead of the `hyper` reference
As a consequence, `revamp_accessor` can not alter the way and the moment the original method is evaluated.
“` revamp_accessor
:foo, :bar do |selector, this, result|
puts "result of sending #{selector} to #{this} is #{result}" result
end “`
:warning: the block will not be called on a `nil` result
# File lib/mumukit/core/module.rb, line 61 def revamp_accessor(*selectors, &block) revamp(*selectors) do |selector, this, hyper| result = hyper.call result && block.call(selector, this, result) end end
# File lib/mumukit/core/module.rb, line 92 def rewrite(selector, &block) raise "method #{selector} was not previously defined here" unless method_defined?(selector) define_method selector, &block end