31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/dsl_accessor/accessor.rb', line 31
def dsl_accessor(*args, &block)
opts = Optionize.new(args, :name, :default)
name = opts.name
if !name and !block
raise "dsl_accessor expects at least one arg"
end
writer =
case opts.writer
when NilClass then Proc.new{|value| value}
when Symbol then Proc.new{|value| __send__(opts.writer, value)}
when Proc then opts.writer
else raise TypeError, "DSL Error: writer should be a symbol or proc. but got `#{opts.writer.class}'"
end
dsl_accessor_set("#{name}_writer", writer)
default =
case opts.default
when NilClass then nil
when [] then Proc.new{[]}
when {} then Proc.new{{}}
when Symbol then Proc.new{__send__(opts.default)}
when Proc then opts.default
else Proc.new{opts.default}
end
dsl_accessor_set("#{name}_default", default)
meta_class = (class << self; self; end)
if opts.instance and !is_a?(Class)
raise ArgumentError, ":instance option is implemented in only Class"
end
case opts.instance
when nil
when true
delegate name, :to=>"self.class"
when Symbol
module_eval(<<-EOS, "(__DSL_ACCESSOR__)", 1)
def #{ name }
@#{opts.instance} or
raise TypeError, "DSL Error: missing @#{opts.instance} for %s##{name}" % self.class.name
@#{opts.instance}.respond_to?(:[]) or
raise TypeError, "DSL Error: expected @#{opts.instance}[] is implemented (%s##{name})" % self.class.name
@#{opts.instance}[:#{ name }] || self.class.#{ name }
end
EOS
else
raise TypeError, "DSL Error: :instance should be true or Symbol, but got `%s' class" % opts.instance.class
end
instance_eval <<-EOS
def #{name}(*args)
dsl_accessor_reader("#{name}", *args)
end
def #{name}=(*args)
dsl_accessor_writer("#{name}", *args)
end
EOS
end
|