base/maroon_base.rb in maroon-0.6.5 vs base/maroon_base.rb in maroon-0.7.0

- old
+ new

@@ -17,251 +17,293 @@ # say do # @who #could be self as well to refer to the current role player of the 'who' role # end # end # greeting do -# p "Hello #{who.say}!" +# p 'Hello #{who.say}!' # end # end # # class Greeter # def initialize(player) # #@who = player # end # end # -# Greeter.new('world').greeting #Will print "Hello world!" +# Greeter.new('world').greeting #Will print 'Hello world!' #maroon is base on Marvin which was the first injectionless language for DCI #being injectionless there's no runtime extend or anything else impacting the performance. There' only regular method invocation even when using role methods #Author:: Rune Funch Søltoft (funchsoltoft@gmail.com) #License:: Same as for Ruby ## -Context::generate_files_in 'generated' -context :Context do - role :roles do - end - role :interactions do - end - role :defining_role do - end - role :role_alias do - end - role :alias_list do - end - role :cached_roles_and_alias_list do - end +c = context :Context do - #define is the only exposed method and can be used to define a context (class) - #if maroon/kernel is required calling context of Context::define are equivalent - #params - #name:: the name of the context. Since this is used as the name of a class, class naming convetions should be used - #block:: the body of the context. Can include definitions of roles (through the role method) or definitions of interactions - #by simply calling a method with the name of the interaction and passing a block as the body of the interaction - define :block => :block, :self => self do |*args| + def self.define(*args, &block) @@with_contracts ||= nil @@generate_file_path ||= nil - alias method_missing role_or_interaction_method + (alias :method_missing :role_or_interaction_method) + base_class, ctx, default_interaction, name = self.send(:create_context_factory, args, block) - ctx.generate_files_in(args.last()) if args.last().instance_of? FalseClass or args.last().instance_of? TrueClass - return ctx.send(:finalize, name, base_class, default_interaction) + if (args.last.instance_of?(FalseClass) or args.last.instance_of?(TrueClass)) then + ctx.generate_files_in(args.last) + end + return ctx.send(:finalize, name, base_class, default_interaction, @@generate_file_path, @@with_contracts) + end - generate_files_in :block => :b,:self => self do |*args| - return role_or_interaction_method(:generate_files_in, *args, &b) if block_given? - + def self.generate_files_in(*args, &b) + if block_given? then + return role_or_interaction_method(:generate_files_in, *args, &b) + end @@generate_file_path = args[0] + end private - with_contracts self do |*args| - return @@with_contracts if args.length == 0 + + def get_definitions(b) + sexp = b.to_sexp + unless is_definition? sexp[3] + sexp = sexp[3] + if sexp + sexp = sexp.select do |exp| + is_definition? exp + end + end + sexp ||= [] + end + + sexp.select do |exp| + is_definition? exp + end + end + + def self.create_context_factory(args, block) + name, base_class, default_interaction = *args + if default_interaction and (not base_class.instance_of?(Class)) then + base_class = eval(base_class.to_s) + end + if base_class and ((not default_interaction) and (not base_class.instance_of?(Class))) then + base_class, default_interaction = default_interaction, base_class + end + ctx = Context.new + ctx.instance_eval { + sexp = block.to_sexp + temp_block = sexp[3] + i = 0 + + while i < temp_block.length + exp = temp_block[i] + unless temp_block[i-2] && temp_block[i-2][0] == :call && temp_block[i-1] && temp_block[i-1][0] == :args + if exp[0] == :defn || exp[0] == :defs + add_method(exp) + temp_block.delete_at i + i -= 1 + elsif exp[0] == :call && exp[1] == nil && exp[2] == :private + @private = true + end + end + i += 1 + end + ctx.instance_eval &block + } + + return [base_class, ctx, default_interaction, name] + + end + + def self.with_contracts(*args) + return @@with_contracts if (args.length == 0) value = args[0] - raise 'make up your mind! disabling contracts during execution will result in undefined behavior' if @@with_contracts && !value + if @@with_contracts and (not value) then + raise('make up your mind! disabling contracts during execution will result in undefined behavior') + end @@with_contracts = value + end - ## - #Defines a role with the given name - #role methods can be defined inside a block passed to this method - # = Example - # role :who do - # say do - # p @who - # end - # end - #The above code defines a role called 'who' with a role method called say - ## - role :block => :b do |*args| - role_name = args[0] - return role_or_interaction_method(:role, *args, &b) if args.length != 1 or not (role_name.instance_of? Symbol) + def createInfo(definition) + MethodInfo.new(definition, @defining_role, @private) + end + def is_definition?(exp) + exp && (exp[0] == :defn || exp[0] == :defs) + end + + def role(*args, &b) + role_name = args[0] + if (args.length.!=(1) or (not role_name.instance_of?(Symbol))) then + return role_or_interaction_method(:role, *args, &b) + end @defining_role = role_name + @roles = {} unless @roles @roles[role_name] = Hash.new - yield if block_given? - @defining_role = nil - end - initialize :block => :b do |*args| - if block_given? - role_or_interaction_method(:initialize, *args, &b) - else - @roles = Hash.new - @interactions = Hash.new - @role_alias = Hash.new - @contracts = Hash.new + definitions = get_definitions(b) + + definitions.each do |exp| + add_method(exp) end - end - role_or_interaction_method(:private) do - @private = true end - current_interpretation_context :block => :b do |*args| - return role_or_interaction_method(:current_interpretation_context, *args, &b) if block_given? - InterpretationContext.new(roles, contracts, role_alias, nil) + def current_interpretation_context(*args, &b) + if block_given? then + return role_or_interaction_method(:current_interpretation_context, *args, &b) + end + InterpretationContext.new(@roles, @contracts, @role_alias, nil) + end - get_methods :block => :b do |*args| + def get_methods(*args, &b) return role_or_interaction_method(:get_methods, *args, &b) if block_given? name = args[0] sources = (@defining_role ? (@roles[@defining_role]) : (@interactions))[name] - if @defining_role && !sources + if @defining_role and (not sources) then @roles[@defining_role][name] = [] else - (@interactions)[name] = [] + @interactions[name] = [] end - end - role :contracts do end - add_method :block => :b do |*args| + def add_method(*args, &b) return role_or_interaction_method(:add_method, *args, &b) if block_given? - name, method = *args - sources = get_methods(name) - sources << method + exp = args[0] + info = createInfo exp + sources = get_methods(info.name) + (sources << info) end - finalize :block => :b do |*args| + def finalize(*args, &b) return role_or_interaction_method(:finalize, *args, &b) if block_given? - name, base_class, default = *args - + name, base_class, default, file_path, with_contracts = *args code = generate_context_code(default, name) - - if @@generate_file_path + if file_path then name = name.to_s - complete = 'class ' + name + (base_class ? '<< ' + base_class.name : '') + ' - ' + code.to_s + ' - end' - File.open('./' + @@generate_file_path.to_s + '/' + name + '.rb', 'w') { |f| f.write(complete) } + complete = ((((('class ' + name) + (base_class ? (('<< ' + base_class.name)) : (''))) + ' + ') + code.to_s) + ' + end') + File.open((((('./' + file_path.to_s) + '/') + name) + '.rb'), 'w') do |f| + f.write(complete) + end complete else - - c = base_class ? (Class.new base_class) : Class.new - if @@with_contracts - c.class_eval('def self.assert_that(obj) - ContextAsserter.new(self.contracts,obj) - end - def self.refute_that(obj) - ContextAsserter.new(self.contracts,obj,false) - end - def self.contracts - @@contracts - end - def self.contracts=(value) - raise \'Contracts must be supplied\' unless value - @@contracts = value - end') - c.contracts=contracts + c = base_class ? (Class.new(base_class)) : (Class.new) + if with_contracts then + c.class_eval( + 'def self.assert_that(obj) + ContextAsserter.new(self.contracts,obj) +end +def self.refute_that(obj) + ContextAsserter.new(self.contracts,obj,false) +end +def self.contracts + @@contracts +end +def self.contracts=(value) + @@contracts = value +end') + c.contracts = contracts end - Kernel.const_set name, c - temp = c.class_eval(code) - (temp || c) - end - end + Kernel.const_set(name, c) + begin + temp = c.class_eval(code) + rescue SyntaxError + p 'error: ' + code + end - create_context_factory self do |args, block| - name, base_class, default_interaction = *args - #if there's two arguments and the second is not a class it must be an interaction - if default_interaction && (!base_class.instance_of? Class) then - base_class = eval(base_class.to_s) + (temp or c) end - base_class, default_interaction = default_interaction, base_class if base_class and !default_interaction and !base_class.instance_of? Class - ctx = Context.new - ctx.instance_eval &block - return base_class, ctx, default_interaction, name + end - generate_context_code :block => :b do |*args| - return role_or_interaction_method(:generate_context_code, *args, &b) if block_given? + def generate_context_code(*args, &b) + if block_given? then + return role_or_interaction_method(:generate_context_code, *args, &b) + end default, name = args - getters = '' impl = '' interactions = '' @interactions.each do |method_name, methods| methods.each do |method| @defining_role = nil - code = ' ' + (method.build_as_context_method method_name, current_interpretation_context) - if method.is_private - getters << code - else - interactions << code - end + code = (' ' + method.build_as_context_method(current_interpretation_context)) + method.is_private ? ((getters << code)) : ((interactions << code)) end end - - if default - interactions << ' - def self.call(*args) - arity = ' + name.to_s + '.method(:new).arity + if default then + (interactions << ((((((((' + def self.call(*args) + arity = ' + name.to_s) + '.method(:new).arity newArgs = args[0..arity-1] - obj = ' + name.to_s + '.new *newArgs + obj = ') + name.to_s) + '.new *newArgs if arity < args.length methodArgs = args[arity..-1] - obj.' + default.to_s + ' *methodArgs + obj.') + default.to_s) + ' *methodArgs else - obj.' + default.to_s + ' - end + obj.') + default.to_s) + ' + end end - ' - interactions << ' - def call(*args);' + default.to_s + ' *args; end -' + ')) + (interactions << ((' + def call(*args);' + default.to_s) + ' *args; end +')) end - @roles.each do |role, methods| - getters << 'attr_reader :' + role.to_s + ' - ' - + (getters << (('attr_reader :' + role.to_s) + ' + ')) methods.each do |method_name, method_sources| - raise 'Duplicate definition of ' + method_name.to_s unless method_sources.length < 2 - raise 'No source for ' + method_name.to_s unless method_sources.length > 0 - + unless (method_sources.length < 2) then + raise(('Duplicate definition of ' + method_name.to_s)) + end + unless (method_sources.length > 0) then + raise(('No source for ' + method_name.to_s)) + end method_source = method_sources[0] @defining_role = role - rewritten_method_name = 'self_' + role.to_s + '_' + method_name.to_s - definition = method_source.build_as_context_method rewritten_method_name, current_interpretation_context - (impl << ' ' + definition.to_s) if definition + + definition = method_source.build_as_context_method(current_interpretation_context) + (impl << (' ' + definition.to_s)) if definition end end - - - interactions + ' - private -' + getters + ' + private_string = (getters + impl).strip! != '' ? ' + private +' : '' + impl = impl.strip! != '' ? ' ' + impl + ' + ' : ' ' + interactions + private_string + getters + impl + end - role_or_interaction_method({:block => :b}) do |*arguments| + def role_or_interaction_method(*arguments, &b) method_name, on_self = *arguments - unless method_name.instance_of? Symbol + unless method_name.instance_of?(Symbol) then on_self = method_name method_name = :role_or_interaction_method end + raise(('Method with out block ' + method_name.to_s)) unless block_given? - raise 'Method with out block ' + method_name.to_s unless block_given? + end - add_method(method_name, MethodInfo.new(on_self, b.to_sexp, @private)) + def private + @private = true end -end \ No newline at end of file + + def initialize + @roles = {} + @interactions = {} + @role_alias = {} + end + +end + +if c.instance_of? String + file_name = './generated/Context.rb' + p "writing to: " + file_name + File.open(file_name, 'w') do |f| + f.write(c) + end +end