Class: Module
- Inherits:
-
Object
- Object
- Module
- Defined in:
- lib/bud/monkeypatch.rb
Instance Method Summary collapse
-
#bloom(block_name = nil, &block) ⇒ Object
bloom statements to be registered with Bud runtime.
-
#bootstrap(&block) ⇒ Object
a ruby block to be run before timestep 1.
-
#bud_import_table ⇒ Object
:nodoc: all.
-
#import(spec) ⇒ Object
import another module and assign to a qualifier symbol:
import MyModule => :m. - #modules ⇒ Object
-
#state(&block) ⇒ Object
the block of Bloom collection declarations.
Instance Method Details
#bloom(block_name = nil, &block) ⇒ Object
bloom statements to be registered with Bud runtime. optional block_name assigns a name for the block; this is useful documentation, and also allows the block to be overridden in a child class.
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/bud/monkeypatch.rb', line 170 def bloom(block_name=nil, &block) # If no block name was specified, generate a unique name if block_name.nil? @block_id ||= 0 block_name = "#{Module.get_class_name(self)}__#{@block_id}".to_sym @block_id += 1 else unless block_name.class <= Symbol raise Bud::CompileError, "block name must be a symbol: #{block_name}" end end # Note that we don't encode the module name ("self") into the name of the # method. This allows named blocks to be overridden (via inheritance or # mixin) in the same way as normal Ruby methods. meth_name = "__bloom__#{block_name}" # Don't allow duplicate named bloom blocks to be defined within a single # module; this indicates a likely programmer error. if instance_methods(false).include?(meth_name) || instance_methods(false).include?(meth_name.to_sym) raise Bud::CompileError, "duplicate block name: '#{block_name}' in #{self}" end ast = Source.read_block(caller[0]) # pass in caller's location via backtrace # ast corresponds only to the statements of the block. Wrap it in a method # definition for backward compatibility for now. # If the block contained multiple statements, the AST will have a top-level # :block node. Since ruby_parser ASTs for method definitions don't contain # such a node, remove it. if ast.nil? ast = [] elsif ast.sexp_type == :block ast = ast.sexp_body else ast = [ast] end ast = s(:defn, meth_name.to_sym, s(:args), *ast) unless self.respond_to? :__bloom_asts__ def self.__bloom_asts__ @__bloom_asts__ ||= {} @__bloom_asts__ end end __bloom_asts__[meth_name] = ast define_method(meth_name.to_sym, &block) end |
#bootstrap(&block) ⇒ Object
a ruby block to be run before timestep 1. one per module.
162 163 164 165 |
# File 'lib/bud/monkeypatch.rb', line 162 def bootstrap(&block) meth_name = "__bootstrap__#{Module.get_class_name(self)}".to_sym define_method(meth_name, &block) end |
#bud_import_table ⇒ Object
:nodoc: all
150 151 152 153 |
# File 'lib/bud/monkeypatch.rb', line 150 def bud_import_table() #:nodoc: all @bud_import_tbl ||= {} @bud_import_tbl end |
#import(spec) ⇒ Object
import another module and assign to a qualifier symbol: import MyModule => :m
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/bud/monkeypatch.rb', line 106 def import(spec) raise Bud::CompileError unless (spec.class <= Hash and spec.length == 1) mod, local_name = spec.first raise Bud::CompileError unless (mod.class <= Module and local_name.class <= Symbol) if mod.class <= Class raise Bud::CompileError, "import must be used with a Module, not a Class" end # A statement like this: # import MyModule => :m # is translated as follows. First, module MyModule is made instantiable by wrapping it in a class # class MyModule__wrap__ # include Bud # include MyModule # end # # Then introduce a method "m", the import binding name, in the calling module/class # (the one with the import statement). This returns an instance of the wrapped class. # inst = MyModule__wrap__.new # def m # inst # end mod, local_name = spec.first if self.method_defined? local_name raise Bud::CompileError, "#{local_name} is already taken" else src = %Q{ def #{local_name} @#{local_name} end def #{local_name}=(val) raise Bud::Error, "type error: expecting an instance of #{mod}" unless val.kind_of? #{mod} @#{local_name} = val end } self.class_eval src end import_tbl = self.bud_import_table import_tbl[local_name] = mod end |
#modules ⇒ Object
101 102 103 |
# File 'lib/bud/monkeypatch.rb', line 101 def modules ancestors[1..-1] end |
#state(&block) ⇒ Object
the block of Bloom collection declarations. one per module.
156 157 158 159 |
# File 'lib/bud/monkeypatch.rb', line 156 def state(&block) meth_name = Module.make_state_meth_name(self) define_method(meth_name, &block) end |