Class: Module

Inherits:
Object show all
Defined in:
lib/mumukit/core/module.rb,
lib/mumukit/core/likeability.rb,
lib/mumukit/core/variability.rb,
lib/mumukit/core/modulability.rb

Instance Method Summary collapse

Instance Method Details

#as_moduleObject



22
23
24
# File 'lib/mumukit/core/modulability.rb', line 22

def as_module
  self
end

#as_module_nameObject



26
27
28
# File 'lib/mumukit/core/modulability.rb', line 26

def as_module_name
  name
end

#as_variable_nameObject



14
15
16
# File 'lib/mumukit/core/variability.rb', line 14

def as_variable_name
  name.as_variable_name
end

#cache_accessor(*selectors) ⇒ Object

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 “‘



86
87
88
89
90
# 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

#like?(other) ⇒ Boolean

Returns:

  • (Boolean)


8
9
10
# File 'lib/mumukit/core/likeability.rb', line 8

def like?(other)
  super || to_s.underscore == other.to_s
end

#patch(selector, &block) ⇒ Object

Redefines a previous definition of the given method. It takes a block with the original arguments and the ‘hyper` reference to the original definition



12
13
14
15
16
# 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

#required(name, message = nil) ⇒ Object



2
3
4
5
6
7
# 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(*selectors, selector_transformer: nil, &block) ⇒ Object

‘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



33
34
35
36
37
38
39
40
41
42
# 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

#revamp_accessor(*selectors, &block) ⇒ Object

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



61
62
63
64
65
66
# 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

#rewrite(selector, &block) ⇒ Object



92
93
94
95
# 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