trace-util-adv 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +7 -0
- data/VERSION +1 -1
- data/lib/README +87 -0
- data/lib/TODO.txt +12 -0
- data/lib/action_handler.rb +99 -0
- data/lib/appenders/appender.rb +97 -0
- data/lib/appenders/appender_registration.rb +16 -0
- data/lib/appenders/base_appender.rb +82 -0
- data/lib/appenders/file_appender.rb +72 -0
- data/lib/appenders/html_appender.rb +94 -0
- data/lib/appenders/logger_appender.rb +84 -0
- data/lib/appenders/stream_appender.rb +37 -0
- data/lib/appenders/template_log_appender.rb +28 -0
- data/lib/appenders/xml_appender.rb +75 -0
- data/lib/core_extensions.rb +101 -0
- data/lib/filters/base_filters.rb +178 -0
- data/lib/filters/composite_filters.rb +71 -0
- data/lib/filters/filter_factory.rb +17 -0
- data/lib/filters/message_filters.rb +35 -0
- data/lib/filters/tracing_filter.rb +88 -0
- data/lib/output_templates.rb +5 -0
- data/lib/rule_match.rb +38 -0
- data/lib/sample_filters.rb +95 -0
- data/lib/templates/base_template.rb +21 -0
- data/lib/templates/html_template.rb +48 -0
- data/lib/templates/string_template.rb +30 -0
- data/lib/templates/trace_output_handler.rb +47 -0
- data/lib/templates/xml_template.rb +36 -0
- data/lib/test_action_handler.rb +34 -0
- data/lib/test_appender.rb +29 -0
- data/lib/test_file_appender.rb +32 -0
- data/lib/test_filters.rb +112 -0
- data/lib/test_filters_chain.rb +100 -0
- data/lib/test_filters_create.rb +28 -0
- data/lib/test_html_appender.rb +66 -0
- data/lib/test_special_filters.rb +78 -0
- data/lib/test_xml_appender.rb +66 -0
- data/lib/test_xml_gen.rb +46 -0
- data/lib/trace_appenders.rb +9 -0
- data/lib/trace_calls.rb +86 -0
- data/lib/trace_ext.rb +57 -0
- data/lib/trace_filters.rb +4 -0
- data/trace-util-adv.gemspec +98 -0
- metadata +44 -2
@@ -0,0 +1,94 @@
|
|
1
|
+
# surround html ouput with wrapper-html
|
2
|
+
# include jquery and css
|
3
|
+
# collapse non-important regions and expand important ones
|
4
|
+
|
5
|
+
# TODO: how to ensure html ouput finishes
|
6
|
+
# file.seek(-20, IO:SEEK_END)
|
7
|
+
module Tracing
|
8
|
+
class HtmlAppender < FileAppender
|
9
|
+
attr_accessor :to_file, :html_output
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def default_path
|
13
|
+
return if !@default_path
|
14
|
+
if !File.exists?(@default_path)
|
15
|
+
FileUtils.mkdir_p @default_path
|
16
|
+
end
|
17
|
+
@default_path
|
18
|
+
end
|
19
|
+
|
20
|
+
def default_path=(path)
|
21
|
+
@default_path = path
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(init_options = nil)
|
26
|
+
@tracer = Tracing::OutputTemplate::HtmlTrace.new
|
27
|
+
super(init_options)
|
28
|
+
@html_output = html_begin
|
29
|
+
|
30
|
+
return if !init_options
|
31
|
+
# write to file
|
32
|
+
@to_file = init_options[:to_file]
|
33
|
+
if @to_file
|
34
|
+
write_wrap_file(to_file)
|
35
|
+
else
|
36
|
+
html_output << html_begin << html_end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_wrap_file(file)
|
41
|
+
file = file_path(file)
|
42
|
+
File.open(file, "w") do |file|
|
43
|
+
file.puts html_begin
|
44
|
+
file.puts html_end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_initial_file(file)
|
49
|
+
write_wrap_file(file)
|
50
|
+
end
|
51
|
+
|
52
|
+
def html_begin
|
53
|
+
%q{<?xml version="1.0" encoding="UTF-8"?>
|
54
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
55
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
56
|
+
<head>
|
57
|
+
<title>Tracing :: abc</title>
|
58
|
+
<link rel="stylesheet" href="tracing.css" type="text/css" media="screen" title="tracing" charset="utf-8">
|
59
|
+
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
|
60
|
+
<script type="text/javascript" src="tracing.js"></script>
|
61
|
+
</head>
|
62
|
+
<body>}
|
63
|
+
end
|
64
|
+
|
65
|
+
def html_end
|
66
|
+
%q{
|
67
|
+
</body>
|
68
|
+
</html>
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
# perform append
|
73
|
+
# perform append
|
74
|
+
def allow_append(txt, context)
|
75
|
+
# check if BEGIN or END
|
76
|
+
if txt.include?('BEGIN')
|
77
|
+
txt = tracer.handle_before_call(context)
|
78
|
+
elsif txt.include?('END')
|
79
|
+
txt = tracer.handle_after_call(context)
|
80
|
+
end
|
81
|
+
|
82
|
+
if to_file
|
83
|
+
insert_into_file(to_file, txt, html_end)
|
84
|
+
else
|
85
|
+
# insert into string
|
86
|
+
html_output = txt[0..-html_end.length] + txt + html_end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# silently ignore
|
91
|
+
def not_allow_append(lines, context)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
# append log to STDOUT Logger
|
4
|
+
module Tracing
|
5
|
+
class LoggerAppender < BaseAppender
|
6
|
+
attr_reader :logger
|
7
|
+
|
8
|
+
def stream(options)
|
9
|
+
if options
|
10
|
+
case options[:stream]
|
11
|
+
when :error
|
12
|
+
STDERR
|
13
|
+
else
|
14
|
+
STDOUT
|
15
|
+
end
|
16
|
+
else
|
17
|
+
STDOUT
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def log_lv(options)
|
22
|
+
if options
|
23
|
+
case options[:log_level]
|
24
|
+
when :info
|
25
|
+
Logger::INFO
|
26
|
+
when :warning
|
27
|
+
Logger::WARNING
|
28
|
+
when :fatal
|
29
|
+
Logger::FATAL
|
30
|
+
else
|
31
|
+
Logger::DEBUG
|
32
|
+
end
|
33
|
+
else
|
34
|
+
Logger::DEBUG
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(init_options)
|
39
|
+
@tracer = Tracing::OutputTemplate::StringTrace.new
|
40
|
+
super(init_options)
|
41
|
+
|
42
|
+
if init_options.kind_of? Hash
|
43
|
+
logger_options = init_options[:logger] if init_options
|
44
|
+
end
|
45
|
+
log_stream = stream(logger_options)
|
46
|
+
log_level = log_lv(logger_options)
|
47
|
+
|
48
|
+
@logger ||= Logger.new(log_stream)
|
49
|
+
@logger.level ||= log_level
|
50
|
+
end
|
51
|
+
|
52
|
+
def log_debug(txt)
|
53
|
+
logger.debug txt
|
54
|
+
end
|
55
|
+
|
56
|
+
def log_info(txt)
|
57
|
+
logger.info txt
|
58
|
+
end
|
59
|
+
|
60
|
+
# perform append
|
61
|
+
def allow_append(txt, context)
|
62
|
+
# check if BEGIN or END
|
63
|
+
if txt.include?('BEGIN')
|
64
|
+
txt = tracer.handle_before_call(context)
|
65
|
+
elsif txt.include?('END')
|
66
|
+
txt = tracer.handle_after_call(context)
|
67
|
+
end
|
68
|
+
|
69
|
+
if txt.include?('INFO')
|
70
|
+
log_info txt
|
71
|
+
elsif txt.include?('WARNING')
|
72
|
+
log_warning txt
|
73
|
+
elsif txt.include?('ERROR')
|
74
|
+
log_error txt
|
75
|
+
else
|
76
|
+
log_debug txt
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# silently ignore
|
81
|
+
def not_allow_append(lines, context)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Tracing
|
2
|
+
class StreamAppender < BaseAppender
|
3
|
+
attr_accessor :stream
|
4
|
+
|
5
|
+
def configure_stream(options)
|
6
|
+
@stream = $stdout
|
7
|
+
if options
|
8
|
+
case options[:stream]
|
9
|
+
when :error
|
10
|
+
@stream = $stderr
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(init_options)
|
16
|
+
@tracer = Tracing::OutputTemplate::StringTrace.new
|
17
|
+
super(init_options)
|
18
|
+
configure_stream(init_options)
|
19
|
+
end
|
20
|
+
|
21
|
+
# perform append
|
22
|
+
def allow_append(txt, context)
|
23
|
+
# check if BEGIN or END
|
24
|
+
if txt.include?('BEGIN')
|
25
|
+
txt = tracer.handle_before_call(context)
|
26
|
+
elsif txt.include?('END')
|
27
|
+
txt = tracer.handle_after_call(context)
|
28
|
+
end
|
29
|
+
|
30
|
+
stream.puts txt
|
31
|
+
end
|
32
|
+
|
33
|
+
# silently ignore
|
34
|
+
def not_allow_append(lines, context)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Tracing
|
2
|
+
class TemplateLogAppender < FileAppender
|
3
|
+
|
4
|
+
def initialize(init_options)
|
5
|
+
@tracer = Tracing::OutputTemplate::StringTrace.new
|
6
|
+
super(init_options)
|
7
|
+
end
|
8
|
+
|
9
|
+
# get template path
|
10
|
+
def template_path(context)
|
11
|
+
obj = context[:self]
|
12
|
+
template_path = obj.instance_variable_get :@template_path
|
13
|
+
end
|
14
|
+
|
15
|
+
# perform append
|
16
|
+
def allow_append(lines, context)
|
17
|
+
path = template_path(context)
|
18
|
+
if path
|
19
|
+
log_file = + '.log'
|
20
|
+
write_file(log_file)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# silently ignore
|
25
|
+
def not_allow_append(lines, context)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# append log to xml-stream or file
|
2
|
+
module Tracing
|
3
|
+
class XmlAppender < FileAppender
|
4
|
+
attr_accessor :xml_output, :to_file
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def default_path
|
8
|
+
return if !@default_path
|
9
|
+
if !File.exists?(@default_path)
|
10
|
+
FileUtils.mkdir_p @default_path
|
11
|
+
end
|
12
|
+
@default_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def default_path=(path)
|
16
|
+
@default_path = path
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(init_options)
|
21
|
+
@tracer = Tracing::OutputTemplate::XmlTrace.new
|
22
|
+
super(init_options)
|
23
|
+
@xml_output = xml_begin
|
24
|
+
|
25
|
+
return if !init_options
|
26
|
+
# write to file
|
27
|
+
@to_file = init_options[:to_file]
|
28
|
+
if @to_file
|
29
|
+
write_wrap_file(to_file)
|
30
|
+
else
|
31
|
+
xml_output << xml_begin << xml_end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_initial_file(file)
|
36
|
+
write_wrap_file(file)
|
37
|
+
end
|
38
|
+
|
39
|
+
def write_wrap_file(file)
|
40
|
+
File.open(file, "w") do |file|
|
41
|
+
file.puts xml_begin
|
42
|
+
file.puts xml_end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def xml_begin
|
47
|
+
"<?xml version='1.0' encoding='UTF-8'?>\n<tracing>\n"
|
48
|
+
end
|
49
|
+
|
50
|
+
def xml_end
|
51
|
+
"</tracing>"
|
52
|
+
end
|
53
|
+
|
54
|
+
# perform append
|
55
|
+
def allow_append(txt, context)
|
56
|
+
# check if BEGIN or END
|
57
|
+
if txt.include?('BEGIN')
|
58
|
+
txt = tracer.handle_before_call(context)
|
59
|
+
elsif txt.include?('END')
|
60
|
+
txt = tracer.handle_after_call(context)
|
61
|
+
end
|
62
|
+
|
63
|
+
if to_file
|
64
|
+
insert_into_file(to_file, txt, xml_end)
|
65
|
+
else
|
66
|
+
# insert into string
|
67
|
+
xml_output = xml_output[0..-xml_end.length] + txt + xml_end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# silently ignore
|
72
|
+
def not_allow_append(lines, context)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'rule_match'
|
2
|
+
|
3
|
+
class String
|
4
|
+
def modules
|
5
|
+
self.split("::")[0..-2]
|
6
|
+
end
|
7
|
+
|
8
|
+
def class_name
|
9
|
+
self.split("::")[-1..-1]
|
10
|
+
end
|
11
|
+
|
12
|
+
def in_module?(module_name)
|
13
|
+
modules = self.modules
|
14
|
+
modules.include?(module_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def split_names
|
18
|
+
self.split(/\s|,/)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
class Array
|
25
|
+
include Tracing::RuleMatch
|
26
|
+
|
27
|
+
def add(obj)
|
28
|
+
self << obj
|
29
|
+
self.flatten!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Symbol
|
34
|
+
def prefix(pre)
|
35
|
+
(pre.to_s + self.to_s).to_sym
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Hash
|
40
|
+
include Tracing::RuleMatch
|
41
|
+
|
42
|
+
def try_create_filter(symbol)
|
43
|
+
isymbol = has_i(symbol) || has_x(symbol)
|
44
|
+
# puts "try_create_filter: " + isymbol.inspect
|
45
|
+
if isymbol
|
46
|
+
filter_names = self[isymbol]
|
47
|
+
# puts "filter_names:" + filter_names.inspect
|
48
|
+
{symbol => {:include => filter_names}}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def rules_allow_action(name)
|
53
|
+
rule_allow_action(name)
|
54
|
+
end
|
55
|
+
|
56
|
+
def rule_list(rules)
|
57
|
+
if rules.kind_of? String
|
58
|
+
rules.split_names
|
59
|
+
else
|
60
|
+
rules
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# return a symbol, either - :include, :exclude or :yield (let next filter decide)
|
65
|
+
def rule_allow_action(name)
|
66
|
+
include_rules = rule_list(self[:include])
|
67
|
+
if include_rules && include_rules.size > 0
|
68
|
+
# puts "Rule include"
|
69
|
+
res = include_rules.matches_any?(name)
|
70
|
+
return :include if res
|
71
|
+
end
|
72
|
+
exclude_rules = rule_list(self[:exclude])
|
73
|
+
if exclude_rules
|
74
|
+
# puts "Rule exclude"
|
75
|
+
return :exclude if exclude_rules.matches_any?(name)
|
76
|
+
end
|
77
|
+
# puts "Not included or excluded"
|
78
|
+
if !self[:default].nil?
|
79
|
+
# puts "Return default: #{self[:default]}"
|
80
|
+
return self[:default]
|
81
|
+
end
|
82
|
+
# puts "Rule yields"
|
83
|
+
return :yield
|
84
|
+
rescue RuleTypeError
|
85
|
+
# puts "error"
|
86
|
+
return :exclude
|
87
|
+
end
|
88
|
+
|
89
|
+
protected
|
90
|
+
def has_i(symbol)
|
91
|
+
isym = symbol.prefix('i')
|
92
|
+
self.has_key?(isym) ? isym : false
|
93
|
+
end
|
94
|
+
|
95
|
+
def has_x(symbol)
|
96
|
+
self.has_key?(symbol.prefix('i'))
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
|
@@ -0,0 +1,178 @@
|
|
1
|
+
module Tracing
|
2
|
+
|
3
|
+
# abstract filter
|
4
|
+
class BaseFilter
|
5
|
+
attr_reader :name
|
6
|
+
attr_accessor :rules
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :filters
|
10
|
+
|
11
|
+
# register symbol => filter mappings
|
12
|
+
def register_filters(hash)
|
13
|
+
filters.merge!(hash)
|
14
|
+
end
|
15
|
+
|
16
|
+
# array of symbols
|
17
|
+
# [:special_filter, :stream_filter]
|
18
|
+
def unregister_filters(hash)
|
19
|
+
filters.reject!{|key, value| hash.include? key}
|
20
|
+
end
|
21
|
+
|
22
|
+
def filter_rule_mappings
|
23
|
+
{
|
24
|
+
:module_rules => :module_filter,
|
25
|
+
:class_rules => :class_filter,
|
26
|
+
:method_rules => :method_filter,
|
27
|
+
:var_rules => :vars_filter,
|
28
|
+
:modules => :composite_module_filter,
|
29
|
+
:classes => :composite_class_filter,
|
30
|
+
:vars => :composite_vars_filter
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def convenience_map
|
35
|
+
{
|
36
|
+
:module => :module_filter,
|
37
|
+
:class => :class_filter,
|
38
|
+
:method => :method_filter,
|
39
|
+
:vars => :vars_filter,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def default_filters
|
45
|
+
{
|
46
|
+
:module_filter => Tracing::ModuleFilter,
|
47
|
+
:class_filter => Tracing::ClassFilter,
|
48
|
+
:method_filter => Tracing::MethodFilter,
|
49
|
+
:vars_filter => Tracing::InstanceVarFilter,
|
50
|
+
:composite_module_filter => Tracing::CompositeModuleFilter,
|
51
|
+
:composite_class_filter => Tracing::CompositeClassFilter,
|
52
|
+
:composite_vars_filter => Tracing::CompositeInstanceVarFilter
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_filter(options)
|
57
|
+
convenience_map.select do |key, _filter|
|
58
|
+
return _filter if options.has_key?(key) || options.has_key?(_filter)
|
59
|
+
end
|
60
|
+
filter_rule_mappings.select do |key, _filter|
|
61
|
+
return _filter if options.has_key? key
|
62
|
+
end
|
63
|
+
return options
|
64
|
+
end
|
65
|
+
|
66
|
+
# Example:
|
67
|
+
# {:method, :include => 'hello,way'}
|
68
|
+
# {:class, :include => 'A,B', :exclude => 'C'}
|
69
|
+
def filter_by_hash(options)
|
70
|
+
filters ||= default_filters
|
71
|
+
|
72
|
+
# try by factory
|
73
|
+
new_filter = Tracing::Filter.create_filter(options)
|
74
|
+
|
75
|
+
# puts "New filter: #{new_filter.inspect}"
|
76
|
+
|
77
|
+
options = new_filter if new_filter
|
78
|
+
|
79
|
+
# try by other means
|
80
|
+
type = get_filter(options)
|
81
|
+
|
82
|
+
if type && type.kind_of?(Symbol)
|
83
|
+
filter_class = filters[type]
|
84
|
+
|
85
|
+
# puts "filter class: #{filter_class}"
|
86
|
+
|
87
|
+
# ensure options has rules
|
88
|
+
if filter_class
|
89
|
+
filter_class.new(options)
|
90
|
+
else
|
91
|
+
raise Exception, "Filterclass not found"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# TODO: Refactor using symbol map!
|
97
|
+
def create_filter(options)
|
98
|
+
if options.kind_of? Hash
|
99
|
+
_filter = filter_by_hash(options)
|
100
|
+
elsif options.kind_of? BaseFilter
|
101
|
+
options
|
102
|
+
else
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
def initialize(options)
|
110
|
+
@name = options[:name] || "Unknown filter"
|
111
|
+
end
|
112
|
+
|
113
|
+
def name_allow_action(name)
|
114
|
+
res = rules.rules_allow_action(name)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# filter on module
|
119
|
+
class ModuleFilter < BaseFilter
|
120
|
+
def initialize(options)
|
121
|
+
super(options)
|
122
|
+
@rules = options[:module_rules] || {}
|
123
|
+
end
|
124
|
+
|
125
|
+
def allow_action(msg, context)
|
126
|
+
name = context[:full_module_name]
|
127
|
+
allow = name_allow_action(name)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# filter on class name
|
132
|
+
class ClassFilter < BaseFilter
|
133
|
+
def initialize(options)
|
134
|
+
super(options)
|
135
|
+
@rules = options[:class_rules] || {}
|
136
|
+
end
|
137
|
+
|
138
|
+
def allow_action(msg, context)
|
139
|
+
name = context[:class_name]
|
140
|
+
allow = name_allow_action(name)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
# filter on method
|
146
|
+
class MethodFilter < BaseFilter
|
147
|
+
def initialize(options)
|
148
|
+
super(options)
|
149
|
+
@rules = options[:method_rules] || options[:method_filter] || {}
|
150
|
+
end
|
151
|
+
|
152
|
+
def allow_action(msg, context)
|
153
|
+
name = context[:method_name]
|
154
|
+
@encountered ||= []
|
155
|
+
name_allow_action(name)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# filter on instance variables
|
160
|
+
class InstanceVarFilter < BaseFilter
|
161
|
+
attr_accessor :var_name
|
162
|
+
|
163
|
+
def initialize(options)
|
164
|
+
super(options)
|
165
|
+
@rules = options[:var_rules] || {}
|
166
|
+
var_name = options[:var_name]
|
167
|
+
end
|
168
|
+
|
169
|
+
def allow_action(msg, context)
|
170
|
+
obj = context[:self]
|
171
|
+
if var_name.kind_of?(Symbol) || var_name.kind_of?(String)
|
172
|
+
value = obj.instance_variable_get(var_name)
|
173
|
+
return name_allow_action(value)
|
174
|
+
end
|
175
|
+
:yield
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|