module Myco::Component
Attributes
__last__[RW]
__name__[RW]
constant_scope[R]
main[R]
parent[R]
parent_meme[R]
Public Class Methods
new(super_components=[], parent=nil, filename=nil, line=nil)
click to toggle source
# File lib/myco/bootstrap/component.rb, line 26 def self.new super_components=[], parent=nil, filename=nil, line=nil locations = Rubinius::VM.backtrace(1,false) # Walk backwards on the backtrace until a lexical parent meme is found i = 0 parent_meme = nil current = nil while true current = locations[i] break unless current parent_meme = current.constant_scope.myco_meme break if parent_meme i += 1 end @constant_scope = current.constant_scope if current # Get the filename and line from the VM if not specified if !filename || !line location = locations.first filename ||= location.file line ||= location.line end this = Class.new Instance # TODO: avoid extending here to avoid touching/making the singleton_class this.extend self this.instance_eval { @super_components = super_components @parent = parent @main = self @filename = filename @line = line @basename = File.basename @filename @dirname = File.dirname @filename @parent_meme = parent_meme @categories = Rubinius::LookupTable.new Myco.add_thunk_method(self, :__component__, self) } all_categories = Hash.new { |h,k| h[k] = Array.new } super_components.each do |other| this.include other if other.is_a? Component other.each_category do |name, cat| all_categories[name] << cat unless name == :main end end end all_categories.each do |name, supers| this.__new_category__(name, supers, filename, line) end this end
Public Instance Methods
__category__(name)
click to toggle source
# File lib/myco/bootstrap/component.rb, line 128 def __category__ name __get_category__(name) || __new_category__(name) end
Also aliased as: category
__get_category__(name)
click to toggle source
# File lib/myco/bootstrap/component.rb, line 86 def __get_category__ name if name == :main self elsif @categories.key?(name) @categories[name] else # If the category doesn't exist, look for one in the super components. # This allows for categories to be implicitly inherited after the fact. super_cats = [] @super_components.each { |sup| sup.respond_to?(:__get_category__) && ( cat = sup.__get_category__(name) cat && super_cats.push(cat) ) } super_cats.any? && __new_category__(name, super_cats, @filename, @line) end end
__new_category__(name, super_cats=[::Myco::Category], filename=nil, line=nil)
click to toggle source
# File lib/myco/bootstrap/component.rb, line 110 def __new_category__ name, super_cats=[::Myco::Category], filename=nil, line=nil # Get the filename and line from the VM if not specified if !filename || !line location = Rubinius::VM.backtrace(2,false).first filename ||= location.file line ||= location.line end category = Component.new super_cats, self, filename, line category.instance_variable_set(:@main, self) category.__name__ = name category_instance = category.instance meme = declare_meme(name) { category_instance } meme.cache = true __set_category__(name, category) end
__set_category__(name, cat)
click to toggle source
# File lib/myco/bootstrap/component.rb, line 105 def __set_category__ name, cat @categories[name] = cat cat end
each_category(&block)
click to toggle source
# File lib/myco/bootstrap/component.rb, line 134 def each_category &block @categories.each &block end
extend_object(object)
click to toggle source
Extend the given object with this component’s features Called on object.extend(component)
# File lib/myco/bootstrap/component.rb, line 164 def extend_object object singleton_class = Rubinius::Type.object_singleton_class(object) Rubinius::Type.include_modules_from(self, singleton_class.origin) Rubinius::Type.infect(singleton_class, self) object end
include(*others)
click to toggle source
Override Module#include to bypass type checks of others
# File lib/myco/bootstrap/component.rb, line 151 def include *others others.reverse_each do |other| Rubinius::Type.include_modules_from(other, self.origin) # TODO: avoid touching singleton class that doesn't already exist? Rubinius::Type.include_modules_from(other.singleton_class, self.singleton_class.origin) Rubinius::Type.infect(self, other) other.__send__ :included, self end self end
inject_into(object)
click to toggle source
Create a child component of self to act as the component of the object, which is allowed to be a Ruby object (not a Myco::Instance). TODO: re-evaluate usefulness and possibly remove in favor of using extend.
# File lib/myco/bootstrap/component.rb, line 174 def inject_into object object.extend InstanceMethods unless object.is_a? InstanceMethods extend_object object object end
instance() { |instance| ... }
click to toggle source
# File lib/myco/bootstrap/component.rb, line 138 def instance if @instance yield @instance if block_given? else @instance = allocate yield @instance if block_given? @instance.__signal__ :creation if Rubinius::Type.object_respond_to?(@instance, :__signal__) end @instance end
new(**kwargs)
click to toggle source
Create an untracked instance of this component and call setters on the instance with the values given by kwargs.
# File lib/myco/bootstrap/component.rb, line 182 def new **kwargs instance = allocate kwargs.each { |key,val| instance.__send__ :"#{key}=", val } instance end
to_s()
click to toggle source
# File lib/myco/bootstrap/component.rb, line 15 def to_s if defined?(::Myco::Category) && (self < ::Myco::Category) "#{parent.to_s}[#{@__name__}]" elsif @__name__ @__name__.to_s else "#{(@super_components || []).map(&:to_s).join(',')}" \ "(#{@basename}:#{@line.to_s} 0x#{object_id.to_s 16})" end end