On Wed, Aug 27, 2008 at 11:08 AM, Toby C. [email protected]
wrote:
I am currently working on a new release of Labardor, but there still
is sooo much to do, however, you might be interested in the following
code of Labrador.
I am however aware that this implies a rethink of your strategy,
however one of my goals is to explore different behavior based OO
approaches than inheritance and mixins, in case you find that a useful
paradigm shift.
And I appologize for the long post but Labrador just is in no shape
for a new release to Rubyforge.
HTH
Robert
Skip the rest if you are not particularily interested in different OO
approaches.
----------------------------- 8< ------------------------
#–
vim: sts=2 sw=2 tw=0 expandtab nu:
#*
#* Labrador, The Lazy Programmer’s Best Friend.
#*
#* Distributed under the terms of the BSD License.
#* Copyright (c) 2007 Robert D.
#* All rights reserved.
#*
#* Redistribution and use in source and binary forms, with or without
#* modification, are permitted provided that the following conditions
are met:
#* * Redistributions of source code must retain the above copyright
#* notice, this list of conditions and the following disclaimer.
#* * Redistributions in binary form must reproduce the above
copyright
#* notice, this list of conditions and the following disclaimer in
the
#* documentation and/or other materials provided with the
distribution.
#* * Neither the name of the Labrador packahe nor the
#* names of its contributors may be used to endorse or promote
products
#* derived from this software without specific prior written
permission.
#*
#* THIS SOFTWARE IS PROVIDED BY Robert D. ``AS IS’’ AND ANY
#* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED
#* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE
#* DISCLAIMED. IN NO EVENT SHALL Robert D. BE LIABLE FOR ANY
#* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES
#* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES;
#* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND
#* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT
#* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS
#* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#++
class Array
def ivar_names_to_strings
map { |ele| ele.to_s.sub(“@”,“”) }
end
def ivar_names_to_symbols
map { |ele| ele.to_s.sub(“@”,“”).to_sym }
end
def names_to_ivar_strings
map { |ele| “@#{ele.to_s.sub(”@“,”“)}” }
end
def names_to_ivar_symbols
map { |ele| “@#{ele.to_s.sub(”@“,”“)}”.to_sym }
end
end # class Array
class Object
def get_ivars *ivars
ivars = instance_variables if ivars.empty?
ivars.ivar_names_to_symbols.
inject( {} ) { |h, ivar|
h.update ivar => instance_variable_get( “@#{ivar}” )
}
end
def pop_ivars
set_ivars! @ivar_stack.pop
end
def push_ivars hash
( @ivar_stack ||= [] ).
push(
get_ivars( *hash.keys )
)
set_ivars! hash
end
def set_ivars hash
hash.keys.each do
| ivar |
ivar_name = “@#{ivar}”.sub( /^@@/, “@” )
instance_variable_set ivar_name, hash[ ivar ] unless
instance_variables.include? ivar_name
end
end
def set_ivars! hash
hash.keys.each do
| ivar |
ivar_name = “@#{ivar}”.sub( /^@@/, “@” )
instance_variable_set ivar_name, hash[ ivar ]
end
end
def set_only_ivars hash, *keys
set_ivars hash.keys.inject( {} ){ |h, k|
keys.include?( k ) ? h.update( k => hash[k] ) : h
}
end # def set_only_ivars hash, *keys
def set_only_ivars! hash, *keys
set_ivars! hash.keys.inject( {} ){ |h, k|
keys.include?( k ) ? h.update( k => hash[k] ) : h
}
end # def set_only_ivars hash, *keys
end # class Object
class Behavior
attr_reader :block
def initialize &blk
@block = blk
end
end
module Kernel
def Behavior &blk
Behavior::new &blk
end
end
class Module
def empty?; instance_methods.empty? end
def empty!; instance_methods.each do |im| remove_method im end end
end
module Pushable
CannotPopException = Class::new RuntimeError
ArgumentError = Class::new ::ArgumentError
def pop_behavior
@bsp -= 1
raise CannotPopException, “empty entity #{self}” if @bsp < 0
@behavior_stack[@bsp].empty!
end
def push_behavior *behaviors, &blk
@behavior_stack ||= []
@bsp ||= 0
raise ArgumentError,
“push_behavior takes at least one behavior or block” if
behaviors.empty? and blk.nil?
behaviors.each do |behavior|
_push_behavior behavior
end
_push_behavior blk if blk
self
end
private
def _push_behavior behavior
m = @behavior_stack[@bsp]
@behavior_stack << ( m = Module::new ) unless m
include m rescue extend m # this is autoprotected against double
inclusion; so finally turns out it is a feature 
m.empty!
m.module_eval &(behavior.block rescue behavior)
@bsp += 1
end
end # module Pushable
class << Pushable
def new *args, &blk
c = Class::new( *args, &blk )
c.extend self
c
end
end # class << Pushable
class << PushableModule = Module::new
def new *args, &blk
m = Module::new( *args, &blk )
m.extend Pushable
m
end
end
------------------------------------ 8<