ruby-beautify 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.md +5 -0
- data/bin/rbeautify +29 -0
- data/lib/app.rb +79 -0
- data/lib/beautifier.rb +168 -0
- data/lib/cli.rb +81 -0
- data/lib/filemagic.rb +13 -0
- data/lib/rbeautify.rb +27 -0
- data/lib/rbeautify/block_end.rb +23 -0
- data/lib/rbeautify/block_matcher.rb +153 -0
- data/lib/rbeautify/block_start.rb +119 -0
- data/lib/rbeautify/config/ruby.rb +131 -0
- data/lib/rbeautify/language.rb +37 -0
- data/lib/rbeautify/line.rb +53 -0
- data/license.txt +77 -0
- data/rbeautify.gemspec +15 -0
- data/spec/fixtures/ruby.yml +408 -0
- data/spec/rbeautify/block_matcher_spec.rb +89 -0
- data/spec/rbeautify/block_start_spec.rb +51 -0
- data/spec/rbeautify/config/ruby_spec.rb +183 -0
- data/spec/rbeautify/line_spec.rb +73 -0
- data/spec/rbeautify_spec.rb +1 -0
- data/spec/spec_helper.rb +124 -0
- metadata +95 -0
data/.gitignore
ADDED
data/README.md
ADDED
data/bin/rbeautify
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'rbeautify'
|
3
|
+
require 'app'
|
4
|
+
require 'cli'
|
5
|
+
require 'filemagic'
|
6
|
+
|
7
|
+
include ErnieBrodeur
|
8
|
+
|
9
|
+
App.version = "0.9.0"
|
10
|
+
App.banner = "Usage: print ruby into a pretty format, or break trying."
|
11
|
+
|
12
|
+
Options.parse!
|
13
|
+
|
14
|
+
if ARGV.empty?
|
15
|
+
begin
|
16
|
+
puts RBeautify.beautify_string :ruby, STDIN
|
17
|
+
rescue Exception => e
|
18
|
+
puts e.message
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
else
|
22
|
+
ARGV.each do |f|
|
23
|
+
if File.exist? f
|
24
|
+
puts RBeautify.beautify_string :ruby, open(f).read
|
25
|
+
else
|
26
|
+
puts "No such file: #{f}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/app.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
$:.push '/home/ebrodeur/Projects/bin_snippets/lib'
|
2
|
+
|
3
|
+
# Some requires, they don't fit elsewhere.
|
4
|
+
require 'yajl'
|
5
|
+
require 'sys/proctable'
|
6
|
+
module ErnieBrodeur
|
7
|
+
|
8
|
+
class Application
|
9
|
+
attr_accessor :version
|
10
|
+
attr_accessor :banner
|
11
|
+
attr_accessor :long_description
|
12
|
+
attr_accessor :plugins
|
13
|
+
|
14
|
+
# return the name of the app, for now this is just the cmd ran, later it will be
|
15
|
+
# something generated but more unique.
|
16
|
+
def name
|
17
|
+
$0.split("/").last
|
18
|
+
end
|
19
|
+
|
20
|
+
def cache_dir
|
21
|
+
"#{Dir.home}/.cache/erniebrodeur/#{App.name}/"
|
22
|
+
end
|
23
|
+
|
24
|
+
def config_dir
|
25
|
+
"#{Dir.home}/.config/erniebrodeur/#{App.name}/"
|
26
|
+
end
|
27
|
+
|
28
|
+
def pids
|
29
|
+
a = Sys::ProcTable.ps.select{|x| x.cmdline =~ /.*#{App.name}.*-[dD].*/}.map {|x| x.pid}
|
30
|
+
a.delete $$
|
31
|
+
return a if a.any?
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@version = '0.0.0'
|
37
|
+
@banner = 'A bin snippet by Ernie Brodeur that does . . . something.'
|
38
|
+
@long_description = ''
|
39
|
+
@plugins = []
|
40
|
+
end
|
41
|
+
|
42
|
+
def daemonize(*params, &block)
|
43
|
+
if params[0] && !params[0][:multiple_pids] && pids
|
44
|
+
puts_or_log :info, "#{App.name} appears to be running (#{pids}), only one allowed, exiting."
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
puts_or_log :info, "Forking to background."
|
48
|
+
|
49
|
+
Process.daemon
|
50
|
+
block.call
|
51
|
+
end
|
52
|
+
|
53
|
+
def kill_daemon
|
54
|
+
if !pids
|
55
|
+
puts_or_log :fatal, "No pids found, exiting."
|
56
|
+
end
|
57
|
+
|
58
|
+
pids.each do |p|
|
59
|
+
puts_or_log :info, "Killing #{p}"
|
60
|
+
%x[kill -TERM #{p}]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
private
|
64
|
+
def puts_or_log(l, s)
|
65
|
+
if App.plugins.include? 'logging'
|
66
|
+
Log.send l, s
|
67
|
+
else
|
68
|
+
puts s
|
69
|
+
exit if l.to_sym == :fatal
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
App = Application.new
|
75
|
+
|
76
|
+
# This will load a helper, if it exists.
|
77
|
+
f = "#{$:.last}/helpers/#{App.name}.rb"
|
78
|
+
require f if File.exist? f
|
79
|
+
end
|
data/lib/beautifier.rb
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Ruby beautifier, version 2.1, 09/11/2006
|
4
|
+
# Copyright (c) 2006, P. Lutus
|
5
|
+
# Released under the GPL
|
6
|
+
|
7
|
+
# Changes
|
8
|
+
# Craig Williams
|
9
|
+
# 12/26/2011
|
10
|
+
# Modified (very minor) to work with a Sublime Text 2 plugin
|
11
|
+
|
12
|
+
# indent regexp tests
|
13
|
+
|
14
|
+
@indentExp = [
|
15
|
+
/^module\b/,
|
16
|
+
/^if\b/,
|
17
|
+
/^\@{0,2}[\w\.]*[\s\t]*\=[\s\t]*if\b/,
|
18
|
+
/(=\s*|^)until\b/,
|
19
|
+
/(=\s*|^)for\b/,
|
20
|
+
/^unless\b/,
|
21
|
+
/^\@{0,2}[\w\.]*[\s\t]*\=[\s\t]*unless\b/,
|
22
|
+
/(=\s*|^)while\b/,
|
23
|
+
/(=\s*|^)begin\b/,
|
24
|
+
/(^| )case\b/,
|
25
|
+
/\bthen\b/,
|
26
|
+
/^class\b/,
|
27
|
+
/^rescue\b/,
|
28
|
+
/^def\b/,
|
29
|
+
/\bdo\b/,
|
30
|
+
/^else\b/,
|
31
|
+
/^elsif\b/,
|
32
|
+
/^ensure\b/,
|
33
|
+
/\bwhen\b/,
|
34
|
+
/\{[^\}]*$/,
|
35
|
+
/\[[^\]]*$/,
|
36
|
+
/\([^\)]*$/
|
37
|
+
]
|
38
|
+
|
39
|
+
# outdent regexp tests
|
40
|
+
|
41
|
+
@outdentExp = [
|
42
|
+
/^rescue\b/,
|
43
|
+
/^ensure\b/,
|
44
|
+
/^elsif\b/,
|
45
|
+
/^end\b/,
|
46
|
+
/^else\b/,
|
47
|
+
/\bwhen\b/,
|
48
|
+
/^[^\{]*\}/,
|
49
|
+
/^[^\[]*\]/,
|
50
|
+
/^[^\(]*\)/
|
51
|
+
]
|
52
|
+
|
53
|
+
def makeTab(tab)
|
54
|
+
(tab < 0) ? "" : @tabStr * @tabSize * tab
|
55
|
+
end
|
56
|
+
|
57
|
+
def addLine(line,tab)
|
58
|
+
line.strip!
|
59
|
+
line = makeTab(tab)+line if line.length > 0
|
60
|
+
line + "\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
def beautifyRuby(contents)
|
64
|
+
commentBlock = false
|
65
|
+
programEnd = false
|
66
|
+
multiLineArray = Array.new
|
67
|
+
multiLineStr = ""
|
68
|
+
tab = 0
|
69
|
+
source = contents
|
70
|
+
dest = ""
|
71
|
+
source.split("\n").each do |line|
|
72
|
+
if(!programEnd)
|
73
|
+
# detect program end mark
|
74
|
+
if(line =~ /^__END__$/)
|
75
|
+
programEnd = true
|
76
|
+
else
|
77
|
+
# combine continuing lines
|
78
|
+
if(!(line =~ /^\s*#/) && line =~ /[^\\]\\\s*$/)
|
79
|
+
multiLineArray.push line
|
80
|
+
multiLineStr += line.sub(/^(.*)\\\s*$/,"\\1")
|
81
|
+
next
|
82
|
+
end
|
83
|
+
|
84
|
+
# add final line
|
85
|
+
if(multiLineStr.length > 0)
|
86
|
+
multiLineArray.push line
|
87
|
+
multiLineStr += line.sub(/^(.*)\\\s*$/,"\\1")
|
88
|
+
end
|
89
|
+
|
90
|
+
tline = ((multiLineStr.length > 0)?multiLineStr:line).strip
|
91
|
+
if(tline =~ /^=begin/)
|
92
|
+
commentBlock = true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if(commentBlock || programEnd)
|
97
|
+
# add the line unchanged
|
98
|
+
dest += line + "\n"
|
99
|
+
else
|
100
|
+
commentLine = (tline =~ /^#/)
|
101
|
+
if(!commentLine)
|
102
|
+
# throw out sequences that will
|
103
|
+
# only sow confusion
|
104
|
+
while tline.gsub!(/'.*?'/,"")
|
105
|
+
end
|
106
|
+
while tline.gsub!(/".*?"/,"")
|
107
|
+
end
|
108
|
+
while tline.gsub!(/\`.*?\`/,"")
|
109
|
+
end
|
110
|
+
while tline.gsub!(/\{[^\{]*?\}/,"")
|
111
|
+
end
|
112
|
+
while tline.gsub!(/\([^\(]*?\)/,"")
|
113
|
+
end
|
114
|
+
while tline.gsub!(/\/.*?\//,"")
|
115
|
+
end
|
116
|
+
while tline.gsub!(/%r(.).*?\1/,"")
|
117
|
+
end
|
118
|
+
tline.gsub!(/\\\"/,"'")
|
119
|
+
@outdentExp.each do |re|
|
120
|
+
if(tline =~ re)
|
121
|
+
tab -= 1
|
122
|
+
break
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
if (multiLineArray.length > 0)
|
127
|
+
multiLineArray.each do |ml|
|
128
|
+
dest += addLine(ml,tab)
|
129
|
+
end
|
130
|
+
multiLineArray.clear
|
131
|
+
multiLineStr = ""
|
132
|
+
else
|
133
|
+
dest += addLine(line,tab)
|
134
|
+
end
|
135
|
+
if(!commentLine)
|
136
|
+
@indentExp.each do |re|
|
137
|
+
if(tline =~ re && !(tline =~ /\s+end\s*$/))
|
138
|
+
tab += 1
|
139
|
+
break
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
if(tline =~ /^=end/)
|
145
|
+
commentBlock = false
|
146
|
+
end
|
147
|
+
end
|
148
|
+
STDOUT.write(dest)
|
149
|
+
# uncomment this to complain about mismatched blocks
|
150
|
+
# if(tab != 0)
|
151
|
+
# STDERR.puts "#{path}: Indentation error: #{tab}"
|
152
|
+
# end
|
153
|
+
end
|
154
|
+
|
155
|
+
tab_or_space = ARGV.first
|
156
|
+
path = ARGV.last
|
157
|
+
path.gsub!("\\", "/") if RUBY_PLATFORM =~ /mswin/
|
158
|
+
contents = IO.read(path)
|
159
|
+
|
160
|
+
if tab_or_space == 'space'
|
161
|
+
@tabSize = 2
|
162
|
+
@tabStr = " "
|
163
|
+
else
|
164
|
+
@tabSize = 1
|
165
|
+
@tabStr = "\t"
|
166
|
+
end
|
167
|
+
|
168
|
+
beautifyRuby(contents)
|
data/lib/cli.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# This library is to reduce the amount of effort I need to build a binary with option parsing
|
2
|
+
# and sensable defaults. It is not intended to be convient for anybody but me, their
|
3
|
+
# are a host of good @options out there if you want cli tools.
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
module ErnieBrodeur
|
7
|
+
class OptBlob
|
8
|
+
def initialize
|
9
|
+
@options = {}
|
10
|
+
|
11
|
+
@parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = ErnieBrodeur::App.banner
|
13
|
+
|
14
|
+
opts.on("-V", "--version", "Print version") { |version| @options[:version] = true}
|
15
|
+
opts.on("-p", "--pry", "open a pry shell.") { |pry| @options[:pry] = true}
|
16
|
+
if App.plugins.include? 'logging'
|
17
|
+
opts.on("-l", "--log-level LEVEL", "Change the log level, default is debug.") { |level| ErnieBrodeur::Log.level level }
|
18
|
+
opts.on("--log-file FILE", "What file to output to, default is STDOUT") { |file| ErnieBrodeur::Log.filename file }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#TODO figure out a more dynamic way to include the parser and hash table.
|
24
|
+
def []=(key, value)
|
25
|
+
@options[key] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](key)
|
29
|
+
@options[key]
|
30
|
+
end
|
31
|
+
|
32
|
+
# This will build an on/off option with a default value set to false.
|
33
|
+
def bool_on(word, description = "")
|
34
|
+
Options[word.to_sym] = false
|
35
|
+
@parser.on "-#{word.chars.first}", "--[no]#{word}", description do |o|
|
36
|
+
Options[word.to_sym] == o
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# This is the parser value on lifted up.
|
41
|
+
def on(*opts, &block)
|
42
|
+
@parser.on(*opts, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_tail(*opts, &block)
|
46
|
+
@parser.on(*opts, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_head(*opts, &block)
|
50
|
+
@parser.on(*opts, &block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def parse!
|
54
|
+
@parser.banner = ErnieBrodeur::App.banner
|
55
|
+
@parser.parse!
|
56
|
+
|
57
|
+
if @options[:version]
|
58
|
+
puts ErnieBrodeur::App.version
|
59
|
+
exit 0
|
60
|
+
end
|
61
|
+
|
62
|
+
# we need to mash in our config array. To do this we want to make config
|
63
|
+
# options that don't overwrite cli options.
|
64
|
+
if App.plugins.include? 'config'
|
65
|
+
Config.each do |k,v|
|
66
|
+
@options[k] = v if !@options[k]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def on_pry
|
72
|
+
if @options[:pry]
|
73
|
+
require 'pry'
|
74
|
+
binding.pry
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
App.plugins.push "cli"
|
80
|
+
Options = OptBlob.new
|
81
|
+
end
|
data/lib/filemagic.rb
ADDED
data/lib/rbeautify.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rbeautify/block_start'
|
2
|
+
require 'rbeautify/block_end'
|
3
|
+
require 'rbeautify/block_matcher'
|
4
|
+
require 'rbeautify/language'
|
5
|
+
require 'rbeautify/line'
|
6
|
+
|
7
|
+
require 'rbeautify/config/ruby'
|
8
|
+
|
9
|
+
module RBeautify
|
10
|
+
|
11
|
+
def self.beautify_string(language, source, use_tabs=false)
|
12
|
+
dest = ""
|
13
|
+
block = nil
|
14
|
+
|
15
|
+
unless language.is_a? RBeautify::Language
|
16
|
+
language = RBeautify::Language.language(language)
|
17
|
+
end
|
18
|
+
|
19
|
+
source.lines.each_with_index do |line_content, line_number|
|
20
|
+
line = RBeautify::Line.new(language, line_content, line_number, block, use_tabs)
|
21
|
+
dest += line.format + "\n"
|
22
|
+
block = line.block
|
23
|
+
end
|
24
|
+
|
25
|
+
return dest
|
26
|
+
end
|
27
|
+
end # module RBeautify
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RBeautify
|
2
|
+
|
3
|
+
class BlockEnd
|
4
|
+
|
5
|
+
attr_accessor :block_start, :offset, :match, :after_match
|
6
|
+
|
7
|
+
def initialize(block_start, offset, match, after_match)
|
8
|
+
self.block_start = block_start
|
9
|
+
self.offset = offset
|
10
|
+
self.match = match
|
11
|
+
self.after_match = after_match
|
12
|
+
end
|
13
|
+
|
14
|
+
def end_offset
|
15
|
+
offset + match.length
|
16
|
+
end
|
17
|
+
|
18
|
+
def end_can_also_be_start?
|
19
|
+
block_start.block_matcher.end_can_also_be_start?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module RBeautify
|
2
|
+
|
3
|
+
class BlockMatcher
|
4
|
+
|
5
|
+
attr_reader :language, :name, :starts, :ends, :options
|
6
|
+
|
7
|
+
def initialize(language, name, starts, ends, options = {})
|
8
|
+
@language = language
|
9
|
+
@name = name
|
10
|
+
@starts = starts
|
11
|
+
@ends = ends.nil? ? starts : ends
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def parse(language, original_block, line_number, string, current_offset)
|
17
|
+
block_end = original_block && original_block.parse_block_end(string, current_offset)
|
18
|
+
|
19
|
+
if (block_start = first_block_start(language,
|
20
|
+
original_block,
|
21
|
+
line_number,
|
22
|
+
string,
|
23
|
+
current_offset,
|
24
|
+
block_end.nil? ? nil : block_end.offset))
|
25
|
+
|
26
|
+
block_end = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
if block_end
|
30
|
+
# Check whether the section of the line which is a block end is also a block start
|
31
|
+
if block_end.end_can_also_be_start? &&
|
32
|
+
(block_start_candidate = first_block_start(language, block_end.block_start.parent, line_number, string, current_offset)) &&
|
33
|
+
block_start_candidate.offset == block_end.offset
|
34
|
+
block_start = block_start_candidate
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
if block_start
|
40
|
+
if debug
|
41
|
+
puts "MATCH: '#{string.slice(0, string.length - block_start.match.length - block_start.after_match.length)}<START type=#{block_start.name}>#{block_start.match}</START>#{block_start.after_match}'"
|
42
|
+
end
|
43
|
+
parse(language, block_start, line_number, block_start.after_match, block_start.end_offset)
|
44
|
+
elsif block_end
|
45
|
+
if debug
|
46
|
+
puts "MATCH: '#{string.slice(0, string.length - block_end.match.length - block_end.after_match.length)}<END>#{block_end.match}</END>#{block_end.after_match}'"
|
47
|
+
end
|
48
|
+
parse(language, block_end.block_start.parent, line_number, block_end.after_match, block_end.end_offset)
|
49
|
+
else
|
50
|
+
original_block
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def debug=(value)
|
55
|
+
@debug = value
|
56
|
+
end
|
57
|
+
|
58
|
+
def debug
|
59
|
+
@debug
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def first_block_start(language, parent_block, line_number, string, offset, maximum_offset = nil)
|
64
|
+
first_block_start = nil
|
65
|
+
language.matchers.each do |matcher|
|
66
|
+
if matcher.can_nest?(parent_block)
|
67
|
+
if (block_start_candidate = matcher.parse_block_start(string, parent_block, offset, line_number)) &&
|
68
|
+
(maximum_offset.nil? || maximum_offset > block_start_candidate.offset)
|
69
|
+
first_block_start = block_start_candidate
|
70
|
+
maximum_offset = first_block_start.offset
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
first_block_start
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def parse_block_start(string, parent_block, offset, line_number)
|
79
|
+
if !string.empty? && (match = starts.match(string))
|
80
|
+
RBeautify::BlockStart.new(self, parent_block, line_number, offset + match.begin(0), match[0], match.post_match)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def indent_end_line?(block)
|
85
|
+
evaluate_option_for_block(:indent_end_line, block)
|
86
|
+
end
|
87
|
+
|
88
|
+
def indent_size(block)
|
89
|
+
evaluate_option_for_block(:indent_size, block) || language.indent_size
|
90
|
+
end
|
91
|
+
|
92
|
+
# Look for blocks within the content of this one
|
93
|
+
def parse_content?
|
94
|
+
options[:parse_content] != false
|
95
|
+
end
|
96
|
+
|
97
|
+
# Indent the content of this block
|
98
|
+
def format_content?
|
99
|
+
options[:format_content] != false
|
100
|
+
end
|
101
|
+
|
102
|
+
def can_nest?(parent_block)
|
103
|
+
return false unless parent_block.nil? || parent_block.parse_content?
|
104
|
+
|
105
|
+
if options[:nest_only]
|
106
|
+
parent_block && options[:nest_only].include?(parent_block.name)
|
107
|
+
else
|
108
|
+
parent_block.nil? ||
|
109
|
+
options[:nest_except].nil? || !options[:nest_except].include?(parent_block.name)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def ends?
|
114
|
+
ends != false
|
115
|
+
end
|
116
|
+
|
117
|
+
def end_is_implicit?
|
118
|
+
options[:end] == :implicit
|
119
|
+
end
|
120
|
+
|
121
|
+
def end_can_also_be_start?
|
122
|
+
if ends == starts
|
123
|
+
options[:end_can_also_be_start] == true
|
124
|
+
else
|
125
|
+
options[:end_can_also_be_start] != false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def negate_ends_match?
|
130
|
+
options[:negate_ends_match]
|
131
|
+
end
|
132
|
+
|
133
|
+
# True if blocks can contain the escape character \ which needs to be
|
134
|
+
# checked for on end match
|
135
|
+
def escape_character?
|
136
|
+
options[:escape_character] == true
|
137
|
+
end
|
138
|
+
|
139
|
+
def inspect
|
140
|
+
name
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
def evaluate_option_for_block(key, block)
|
145
|
+
if options[key] && options[key].respond_to?(:call)
|
146
|
+
options[key].call(block)
|
147
|
+
else
|
148
|
+
options[key]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|