module Fiber::Local

def self.extended(klass)

def self.extended(klass)
	attribute_name = klass.name.gsub('::', '_').gsub(/\W/, '').downcase.to_sym
	
	# This is used for the general interface and fiber storage key:
	klass.instance_variable_set(:@fiber_local_attribute_name, attribute_name)
	klass.singleton_class.attr :fiber_local_attribute_name
	
	# This is used for reading and writing directly to the thread instance variables:
	klass.instance_variable_set(:@fiber_local_variable_name, :"@#{attribute_name}")
	
	Thread.attr_accessor(attribute_name)
end

def instance

@returns [Object] The thread-local instance.
Get the current thread-local instance. Create it if required.
def instance
	# This is considered a local "override" in the dynamic scope of the fiber:
	if instance = Fiber[@fiber_local_attribute_name]
		return instance
	end
	
	# This is generally the fast path:
	thread = Thread.current
	unless instance = thread.instance_variable_get(@fiber_local_variable_name)
		if instance = self.local
			thread.instance_variable_set(@fiber_local_variable_name, instance)
		end
	end
	
	return instance
end

def instance= instance

@parameter instance [Object] The object that will become the thread-local instance.
Assigns to the fiber-local instance.
def instance= instance
	Fiber[@fiber_local_attribute_name] = instance
end

def local

@returns [Object]
By default, invokes {new} to generate the instance.
Instantiate a new thread-local object.
def local
	self.new
end