[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dennou-ruby:000189] paramclass.rb
���Ȥ���Ǥ�
���������Хѥ��ȥ�å����饹�������äƤʤ��ä��Τ�����
�ޤ����Ȥ�����Ȥ��ơ��ޤ�����Ĺ����Ȥ����Τ���˼����ޤ���
�ѥ��ȥ�å����饹��¸�����Mix-in�⥸�塼��Parametric����
�Ϥ��θ�ˤ���ޤ���
������ä������Ū��
* �ѥ����֥������ȤǤʤ����饹�����ä������ɤ����
* �����������饹̾��Ϳ����Τ����ݤʾ��
���н褹�뤿��Ǥ���
��ʵ�ǽ�ϡ֥��饹̾(*params)�פǻ��ꤵ�줿�ѥ���params
�饹��åɤ⤷���ϥ�å�parameters�ǻ��ȤǤ���Ȥ���
��ΤǤ���parameters�γ����Ǥΰ�̣�ϰʲ��Υ���ץ�Τ褦�ˡ�
��Ƭ�����������ɤ��Ǥ��礦��
�ޤ��֥��饹̾(*params)�� �ϥ��饹���֤��ޤ��������Υ��饹��
�������Ф��ƥ�ˡ����ʤΤǡ���ƥ��Τ褦�˰����ޤ�(��������
Ruby��ʸˡ�塢������������ʤ����ðۥ��饹����ˤϻȤ��ޤ���)��
paramclass.rb ���Τ�¹Ԥ��������ǽ���±餵��ޤ���
ɬ�������Ψ���ɤ�����ޤ���Τǡ�C����˾������¿����г�ĥ
�⥸�塼��Ȥ��ƺ��ľ���ѰդϤ���ޤ���
require "paramclass"
class FixedSizeArray
include Parametric
include Enumerable
def size; parameters[0]; end
def default_value; parameters[1]; end
def self.[](*args); self.new(*args); end
def initialize(*args)
@xxxxxx = args
s = @xxxxxx
raise ArgumentError, "Too many initial values" if s > size
@xxxxxx(default_value, s, size - s)
end
def [](n)
if n < -size or size <= n
raise IndexError, "index out of range"
end
@xxxxxx[n]
end
def []=(n,v)
if n < -size or size <= n
raise IndexError, "index out of range"
end
ary[n] = v
end
def each(&blk)
@xxxxxx(&blk)
end
def inspect
@xxxxxx
end
end
# example
p a = FixedSizeArray(5, "")["foo", "bar", "baz"]
#=> ["foo", "bar", "baz", "", ""]
p a.is_a? FixedSizeArray(5, "")
#=> true
#
# paramclass.rb
#
# begin: class variable emulation by Matz [ruby-dev:8245]
class Module
private
def module_attr(*names)
names.each do |name|
name = name.id2name unless name.kind_of? String
self.module_eval <<-EOS
CV_#{name} = []
class <<self
def #{name}; CV_#{name}[0] end
def #{name}=(val); CV_#{name}[0] = val end
end
EOS
end
end
end
class Class
private
alias class_attr module_attr
end
# end: class variable emulation by Matz [ruby-dev:8245]
module Parametric
def Parametric.append_features(mod)
super mod
# class generating function
cn = mod.name
eval "def #{cn}(*args); #{cn}.instance_eval{class_generate(*args)} end",
TOPLEVEL_BINDING
mod.module_eval{
class_attr :rootclass, :class_parameters, :classes
@xxxxxx = true
}
mod.rootclass = mod
mod.class_parameters = {}
mod.classes = {nil => mod}
def mod.class_generate(*args)
args = nil if args.empty?
klass = self::classes[args] || self::classes[args] = Class.new(self)
klass.class_parameters[klass] = args unless klass.rootclass?
klass
end
def mod.parameters
if rootclass?
defined?(default_parameters) ? default_parameters : []
else
res = nil
self.ancestors.find{|i| res = class_parameters[i] }
res
end
end
def mod.rootclass?
@xxxxxx
end
end
def parameters
self.type.parameters
end
end
########## devel test ##########
if __FILE__ == $0
def xmp(arg, show = true) # prints expample code and result line by line
if show
__res__ = []
eval arg.gsub(/^(.*)\n?/){ "__res__ << (#{$1}).inspect;" }
arg.split(/\n/).each_with_index{|l,i|
(puts "\n" ; next) if l =~ /^$/
print "#{l}\n #=> #{__res__[i]}\n"
}
else
print arg; eval arg
end
end
xmp <<-EOS, nil
class C
include Parametric
def C.default_parameters
[100]
end
end
EOS
xmp <<-EOS
C.parameters
C(10).parameters
C(10).id == C(10).id
C(20,10) < C
C.rootclass
C(10).rootclass
C.rootclass?
C().rootclass?
C("foo").rootclass?
D = C(0)
C(0)
EOS
xmp <<-EOS, nil
class Bar < D;
include Parametric
def Bar.default_parameters
superclass.parameters + [""]
end
end
EOS
xmp <<-EOS
Bar.rootclass
Bar.parameters
Bar.new.is_a? D
Bar.new.is_a? C(0)
Bar.new.is_a? C(10)
EOS
end