safemode 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of safemode might be problematic. Click here for more details.
- data/LICENCSE +22 -0
- data/README.markdown +71 -0
- data/Rakefile +15 -0
- data/demo.rb +23 -0
- data/init.rb +1 -0
- data/lib/action_view/template_handlers/safe_erb.rb +43 -0
- data/lib/action_view/template_handlers/safe_haml.rb +27 -0
- data/lib/action_view/template_handlers/safemode_handler.rb +28 -0
- data/lib/haml/safemode.rb +41 -0
- data/lib/rubyparser_bug.rb +8 -0
- data/lib/safemode.rb +58 -0
- data/lib/safemode/blankslate.rb +34 -0
- data/lib/safemode/core_ext.rb +39 -0
- data/lib/safemode/core_jails.rb +104 -0
- data/lib/safemode/exceptions.rb +22 -0
- data/lib/safemode/jail.rb +28 -0
- data/lib/safemode/parser.rb +196 -0
- data/lib/safemode/scope.rb +58 -0
- data/safemode.gemspec +14 -0
- data/safemode.rb +1 -0
- data/test/test_all.rb +14 -0
- data/test/test_erb_eval.rb +76 -0
- data/test/test_helper.rb +130 -0
- data/test/test_jail.rb +53 -0
- data/test/test_safemode_eval.rb +68 -0
- data/test/test_safemode_parser.rb +45 -0
- metadata +98 -0
data/LICENCSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2008, Sven Fuchs, Peter Cooper
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
## Safemode
|
2
|
+
|
3
|
+
A library for safe evaluation of Ruby code based on RubyParser and
|
4
|
+
Ruby2Ruby. Provides Rails ActionView template handlers for ERB and Haml.
|
5
|
+
|
6
|
+
### Word of warning
|
7
|
+
|
8
|
+
This library is still highly experimental. Only use it at your own risk for
|
9
|
+
anything beyond experiments and playing.
|
10
|
+
|
11
|
+
That said, please **do** play with it, read and run the unit tests and provide
|
12
|
+
feedback to help make it waterproof and finally suitable for serious purposes.
|
13
|
+
|
14
|
+
### Usage
|
15
|
+
|
16
|
+
For manual evaluation of Ruby code and ERB templates see demo.rb
|
17
|
+
|
18
|
+
You can use the ActionView template handlers by registering them, e.g., in
|
19
|
+
a config/initializer file like this:
|
20
|
+
|
21
|
+
# in config/intializer/safemode_tempate_handlers.rb
|
22
|
+
ActionView::Template.register_template_handler :serb, ActionView::TemplateHandlers::SafeErb
|
23
|
+
ActionView::Template.register_template_handler :haml, ActionView::TemplateHandlers::SafeHaml
|
24
|
+
|
25
|
+
If you register the ERB template handler for the file extension :erb be aware
|
26
|
+
that this most probably will break when your application tries to render an
|
27
|
+
error message in development mode (because Rails will try to use the handler
|
28
|
+
to render the error message itself).
|
29
|
+
|
30
|
+
You will then have to "whitelist" all method calls to the objects that are
|
31
|
+
registered as template variables by explicitely allowing access to them. You
|
32
|
+
can do that by defining a Safemode::Jail class for your classes, like so:
|
33
|
+
|
34
|
+
class User
|
35
|
+
class Jail < Safemode::Jail
|
36
|
+
allow :name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
This will allow your template users to access the name method on your User
|
41
|
+
objects.
|
42
|
+
|
43
|
+
For more details about the concepts behind Safemode please refer to the
|
44
|
+
following blog posts until a more comprehensive writeup is available:
|
45
|
+
|
46
|
+
* Initial reasoning: [http://www.artweb-design.de/2008/2/5/sexy-theme-templating-with-haml-safemode-finally](http://www.artweb-design.de/2008/2/5/sexy-theme-templating-with-haml-safemode-finally)
|
47
|
+
* Refined concept: [http://www.artweb-design.de/2008/2/17/sending-ruby-to-the-jail-an-attemp-on-a-haml-safemode](http://www.artweb-design.de/2008/2/17/sending-ruby-to-the-jail-an-attemp-on-a-haml-safemode)
|
48
|
+
* ActionView ERB handler: [http://www.artweb-design.de/2008/4/22/an-erb-safemode-handler-for-actionview](http://www.artweb-design.de/2008/4/22/an-erb-safemode-handler-for-actionview)
|
49
|
+
|
50
|
+
### Dependencies
|
51
|
+
|
52
|
+
Requires the gems:
|
53
|
+
|
54
|
+
* RubyParser
|
55
|
+
* Ruby2Ruby
|
56
|
+
|
57
|
+
As of writing RubyParser alters StringIO and thus breaks usage with Rails.
|
58
|
+
See [http://www.zenspider.com/pipermail/parsetree/2008-April/000026.html](http://www.zenspider.com/pipermail/parsetree/2008-April/000026.html)
|
59
|
+
|
60
|
+
A patch is included that fixes this issue and can be applied to RubyParser.
|
61
|
+
See lib/ruby\_parser\_string\_io\_patch.diff
|
62
|
+
|
63
|
+
### Credits
|
64
|
+
|
65
|
+
* Sven Fuchs - Maintainer
|
66
|
+
* Peter Cooper
|
67
|
+
|
68
|
+
This code and all of the Safemode library's code was initially written by
|
69
|
+
Sven Fuchs to allow Haml to have a safe mode. It was then modified and
|
70
|
+
re-structured by Peter Cooper and Sven Fuchs to extend the idea to generic
|
71
|
+
Ruby eval situations.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# optional libraries
|
2
|
+
%w[ redgreen ].each do |lib|
|
3
|
+
begin
|
4
|
+
require lib
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
task :default => [:test]
|
10
|
+
|
11
|
+
task :test do
|
12
|
+
['test/unit', 'test/test_helper', 'test/test_all'].each do |file|
|
13
|
+
require file
|
14
|
+
end
|
15
|
+
end
|
data/demo.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'safemode'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
erb_code = %q{<% 10.times do |i| %><%= i %><% end %>}
|
5
|
+
|
6
|
+
raw_code = %q{
|
7
|
+
(1..10).to_a.collect do |i|
|
8
|
+
puts i
|
9
|
+
i * 2
|
10
|
+
end.join(', ')
|
11
|
+
}
|
12
|
+
|
13
|
+
box = Safemode::Box.new
|
14
|
+
|
15
|
+
puts "Doing the ERB code in safe mode\n-----"
|
16
|
+
puts box.eval(ERB.new(erb_code).src)
|
17
|
+
|
18
|
+
puts "\nDoing the regular Ruby code in safe mode\n-----"
|
19
|
+
puts box.eval(raw_code)
|
20
|
+
|
21
|
+
puts "\nOutput from regular Ruby code\n-----"
|
22
|
+
puts box.output
|
23
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'safemode'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'safemode'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module ActionView
|
5
|
+
module TemplateHandlers
|
6
|
+
class SafeErb < TemplateHandler
|
7
|
+
include Compilable rescue nil # does not exist prior Rails 2.1
|
8
|
+
extend SafemodeHandler
|
9
|
+
|
10
|
+
def self.line_offset
|
11
|
+
0
|
12
|
+
end
|
13
|
+
|
14
|
+
def compile(template)
|
15
|
+
# Rails 2.0 passes the template source, while Rails 2.1 passes the
|
16
|
+
# template instance
|
17
|
+
src = template.respond_to?(:source) ? template.source : template
|
18
|
+
filename = template.filename rescue nil
|
19
|
+
erb_trim_mode = '-'
|
20
|
+
|
21
|
+
# code = ::ERB.new(src, nil, @view.erb_trim_mode).src
|
22
|
+
code = ::ERB.new("<% __in_erb_template=true %>#{src}", nil, erb_trim_mode, '@output_buffer').src
|
23
|
+
# Ruby 1.9 prepends an encoding to the source. However this is
|
24
|
+
# useless because you can only set an encoding on the first line
|
25
|
+
RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
|
26
|
+
|
27
|
+
code.gsub!('\\','\\\\\\') # backslashes would disappear in compile_template/modul_eval, so we escape them
|
28
|
+
|
29
|
+
code = <<-CODE
|
30
|
+
handler = ActionView::TemplateHandlers::SafeHaml
|
31
|
+
assigns = handler.valid_assigns(@template.assigns)
|
32
|
+
methods = handler.delegate_methods(self)
|
33
|
+
code = %Q(#{code});
|
34
|
+
|
35
|
+
box = Safemode::Box.new(self, methods, #{filename.inspect}, 0)
|
36
|
+
box.eval(code, assigns, local_assigns, &lambda{ |*args| yield(*args) })
|
37
|
+
CODE
|
38
|
+
# puts code
|
39
|
+
code
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'safemode'
|
2
|
+
require 'haml/safemode'
|
3
|
+
|
4
|
+
module ActionView
|
5
|
+
module TemplateHandlers
|
6
|
+
class SafeHaml < TemplateHandler
|
7
|
+
include Compilable rescue nil # does not exist prior Rails 2.1
|
8
|
+
extend SafemodeHandler
|
9
|
+
|
10
|
+
def self.line_offset
|
11
|
+
3
|
12
|
+
end
|
13
|
+
|
14
|
+
def compile(template)
|
15
|
+
# Rails 2.0 passes the template source, while Rails 2.1 passes the
|
16
|
+
# template instance
|
17
|
+
src = template.respond_to?(:source) ? template.source : template
|
18
|
+
filename = template.filename rescue nil
|
19
|
+
|
20
|
+
options = Haml::Template.options.dup
|
21
|
+
haml = Haml::Engine.new template, options
|
22
|
+
methods = delegate_methods + ActionController::Routing::Routes.named_routes.helpers
|
23
|
+
haml.precompile_for_safemode filename, ignore_assigns, methods
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ActionView
|
2
|
+
module TemplateHandlers
|
3
|
+
module SafemodeHandler
|
4
|
+
|
5
|
+
def valid_assigns(assigns)
|
6
|
+
assigns = assigns.reject{|key, value| skip_assigns.include?(key) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def delegate_methods(view)
|
10
|
+
[ :render, :params, :flash ] +
|
11
|
+
helper_methods(view) +
|
12
|
+
ActionController::Routing::Routes.named_routes.helpers
|
13
|
+
end
|
14
|
+
|
15
|
+
def helper_methods(view)
|
16
|
+
view.class.included_modules.collect {|m| m.instance_methods(false) }.flatten.map(&:to_sym)
|
17
|
+
end
|
18
|
+
|
19
|
+
def skip_assigns
|
20
|
+
[ "_cookies", "_flash", "_headers", "_params", "_request",
|
21
|
+
"_response", "_session", "before_filter_chain_aborted",
|
22
|
+
"ignore_missing_templates", "logger", "request_origin",
|
23
|
+
"template", "template_class", "url", "variables_added",
|
24
|
+
"view_paths" ]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'haml'
|
2
|
+
|
3
|
+
module Haml
|
4
|
+
class Buffer
|
5
|
+
class Jail < Safemode::Jail
|
6
|
+
allow :push_script, :push_text, :_hamlout, :open_tag
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Haml
|
12
|
+
class Engine
|
13
|
+
def precompile_for_safemode(filename, ignore_assigns = [], delegate_methods = [])
|
14
|
+
@precompiled.gsub!('\\','\\\\\\') # backslashes would disappear in compile_template/modul_eval, so we escape them
|
15
|
+
|
16
|
+
<<-CODE
|
17
|
+
buffer = Haml::Buffer.new(#{options_for_buffer.inspect})
|
18
|
+
local_assigns = local_assigns.merge :_hamlout => buffer
|
19
|
+
|
20
|
+
handler = ActionView::TemplateHandlers::SafeHaml
|
21
|
+
assigns = handler.valid_assigns(@template.assigns)
|
22
|
+
methods = handler.delegate_methods(self)
|
23
|
+
code = %Q(#{code});
|
24
|
+
|
25
|
+
box = Safemode::Box.new(self, methods, #{filename.inspect}, 0)
|
26
|
+
box.eval(code, assigns, local_assigns, &lambda{ yield })
|
27
|
+
buffer.buffer
|
28
|
+
CODE
|
29
|
+
|
30
|
+
# preamble = "buffer = Haml::Buffer.new(#{options_for_buffer.inspect})
|
31
|
+
# local_assigns = local_assigns.merge :_hamlout => buffer
|
32
|
+
# assigns = @template.assigns.reject{|key, value| #{ignore_assigns.inspect}.include?(key) };".gsub("\n", ';')
|
33
|
+
#
|
34
|
+
# postamble = "box = Safemode::Box.new(self, #{delegate_methods.inspect})
|
35
|
+
# box.eval(code, assigns, local_assigns, &lambda{ yield })
|
36
|
+
# buffer.buffer".gsub("\n", ';')
|
37
|
+
#
|
38
|
+
# preamble + "code = %Q(#{@precompiled});" + postamble
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/safemode.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'ruby2ruby'
|
4
|
+
begin
|
5
|
+
require 'ruby_parser' # try to load RubyParser and use it if present
|
6
|
+
rescue LoadError => e
|
7
|
+
end
|
8
|
+
# this doesn't work somehow. Maybe something changed inside
|
9
|
+
# ParseTree or sexp_processor or so.
|
10
|
+
# (the require itself works, but ParseTree doesn't play nice)
|
11
|
+
# begin
|
12
|
+
# require 'parse_tree'
|
13
|
+
# rescue LoadError => e
|
14
|
+
# end
|
15
|
+
|
16
|
+
require 'safemode/core_ext'
|
17
|
+
require 'safemode/blankslate'
|
18
|
+
require 'safemode/exceptions'
|
19
|
+
require 'safemode/jail'
|
20
|
+
require 'safemode/core_jails'
|
21
|
+
require 'safemode/parser'
|
22
|
+
require 'safemode/scope'
|
23
|
+
|
24
|
+
module Safemode
|
25
|
+
class << self
|
26
|
+
def jail(obj)
|
27
|
+
find_jail_class(obj.class).new obj
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_jail_class(klass)
|
31
|
+
while klass != Object
|
32
|
+
return klass.const_get('Jail') if klass.const_defined?('Jail')
|
33
|
+
klass = klass.superclass
|
34
|
+
end
|
35
|
+
Jail
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
define_core_jail_classes
|
40
|
+
|
41
|
+
class Box
|
42
|
+
def initialize(delegate = nil, delegate_methods = [], filename = nil, line = nil)
|
43
|
+
@scope = Scope.new(delegate, delegate_methods)
|
44
|
+
@filename = filename
|
45
|
+
@line = line
|
46
|
+
end
|
47
|
+
|
48
|
+
def eval(code, assigns = {}, locals = {}, &block)
|
49
|
+
code = Parser.jail(code)
|
50
|
+
binding = @scope.bind(assigns, locals, &block)
|
51
|
+
result = Kernel.eval(code, binding, @filename || __FILE__, @line || __LINE__)
|
52
|
+
end
|
53
|
+
|
54
|
+
def output
|
55
|
+
@scope.output
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Safemode
|
2
|
+
class Blankslate
|
3
|
+
@@allow_instance_methods = ['class', 'inspect', 'methods', 'respond_to?', 'to_s', 'instance_variable_get']
|
4
|
+
@@allow_class_methods = ['methods', 'new', 'name', 'inspect', '<', 'ancestors', '=='] # < needed in Rails Object#subclasses_of
|
5
|
+
|
6
|
+
silently { undef_methods(*instance_methods - @@allow_instance_methods) }
|
7
|
+
class << self
|
8
|
+
silently { undef_methods(*instance_methods - @@allow_class_methods) }
|
9
|
+
|
10
|
+
def method_added(name) end # ActiveSupport needs this
|
11
|
+
|
12
|
+
def inherited(subclass)
|
13
|
+
subclass.init_allowed_methods(@allowed_methods)
|
14
|
+
end
|
15
|
+
|
16
|
+
def init_allowed_methods(allowed_methods)
|
17
|
+
@allowed_methods = allowed_methods
|
18
|
+
end
|
19
|
+
|
20
|
+
def allowed_methods
|
21
|
+
@allowed_methods ||= []
|
22
|
+
end
|
23
|
+
|
24
|
+
def allow(*names)
|
25
|
+
@allowed_methods = allowed_methods + names.map{|name| name.to_s}
|
26
|
+
@allowed_methods.uniq!
|
27
|
+
end
|
28
|
+
|
29
|
+
def allowed?(name)
|
30
|
+
allowed_methods.include? name.to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Kernel
|
2
|
+
def silently(&blk)
|
3
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
4
|
+
yield
|
5
|
+
$VERBOSE = old_verbose
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Module
|
10
|
+
def undef_methods(*methods)
|
11
|
+
methods.each { |name| undef_method(name) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Object
|
16
|
+
def to_jail
|
17
|
+
Safemode.jail self
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# As every call to an object in the eval'ed string will be jailed by the
|
22
|
+
# parser we don't need to "proactively" jail arrays and hashes. Likewise we
|
23
|
+
# don't need to jail objects returned from a jail. Doing so would provide
|
24
|
+
# "double" protection, but it also would break using a return value in an if
|
25
|
+
# statement, passing them to a Rails helper etc.
|
26
|
+
|
27
|
+
# class Array
|
28
|
+
# def to_jail
|
29
|
+
# Safemode.jail collect{ |obj| obj.to_jail }
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# class Hash
|
34
|
+
# def to_jail
|
35
|
+
# hash = {}
|
36
|
+
# collect{ |key, obj| hash[key] = obj.to_jail}
|
37
|
+
# Safemode.jail hash
|
38
|
+
# end
|
39
|
+
# end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Safemode
|
2
|
+
class << self
|
3
|
+
def define_core_jail_classes
|
4
|
+
core_classes.each do |klass|
|
5
|
+
define_jail_class(klass).allow *core_jail_methods(klass).uniq
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def define_jail_class(klass)
|
10
|
+
unless klass.const_defined?("Jail")
|
11
|
+
klass.const_set("Jail", jail = Class.new(Safemode::Jail))
|
12
|
+
end
|
13
|
+
klass.const_get('Jail')
|
14
|
+
end
|
15
|
+
|
16
|
+
def core_classes
|
17
|
+
klasses = [ Array, Bignum, Fixnum, Float, Hash,
|
18
|
+
Range, String, Symbol, Time ]
|
19
|
+
klasses << Date if defined? Date
|
20
|
+
klasses << DateTime if defined? DateTime
|
21
|
+
klasses
|
22
|
+
end
|
23
|
+
|
24
|
+
def core_jail_methods(klass)
|
25
|
+
@@methods_whitelist[klass.name] + (@@default_methods & klass.instance_methods)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# these methods are allowed in all classes if they are present
|
30
|
+
@@default_methods = %w( % & * ** + +@ - -@ / < << <= <=> == === > >= >> ^ | ~
|
31
|
+
eql? equal? new methods is_a? kind_of? nil?
|
32
|
+
[] []= to_a to_jail to_s inspect to_param )
|
33
|
+
|
34
|
+
# whitelisted methods for core classes ... kind of arbitrary selection
|
35
|
+
@@methods_whitelist = {
|
36
|
+
'Array' => %w(assoc at blank? collect collect! compact compact! concat
|
37
|
+
delete delete_at delete_if each each_index empty? fetch
|
38
|
+
fill first flatten flatten! hash include? index indexes
|
39
|
+
indices inject insert join last length map map! nitems pop
|
40
|
+
push rassoc reject reject! reverse reverse! reverse_each
|
41
|
+
rindex select shift size slice slice! sort sort! transpose
|
42
|
+
uniq uniq! unshift values_at zip),
|
43
|
+
|
44
|
+
'Bignum' => %w(abs ceil chr coerce div divmod downto floor hash
|
45
|
+
integer? modulo next nonzero? quo remainder round
|
46
|
+
singleton_method_added size step succ times to_f to_i
|
47
|
+
to_int to_s truncate upto zero?),
|
48
|
+
|
49
|
+
'Fixnum' => %w(abs ceil chr coerce div divmod downto floor id2name
|
50
|
+
integer? modulo modulo next nonzero? quo remainder round
|
51
|
+
singleton_method_added size step succ times to_f to_i
|
52
|
+
to_int to_s to_sym truncate upto zero?),
|
53
|
+
|
54
|
+
'Float' => %w(abs ceil coerce div divmod finite? floor hash
|
55
|
+
infinite? integer? modulo nan? nonzero? quo remainder
|
56
|
+
round singleton_method_added step to_f to_i to_int to_s
|
57
|
+
truncate zero?),
|
58
|
+
|
59
|
+
'Hash' => %w(blank? clear delete delete_if each each_key each_pair
|
60
|
+
each_value empty? fetch has_key? has_value? include? index
|
61
|
+
invert key? keys length member? merge merge! rec_merge! rehash
|
62
|
+
reject reject! select shift size sort store
|
63
|
+
update value? values values_at),
|
64
|
+
|
65
|
+
'Range' => %w(begin each end exclude_end? first hash include?
|
66
|
+
include_without_range? last member? step),
|
67
|
+
|
68
|
+
'String' => %w(blank? capitalize capitalize! casecmp center chomp chomp!
|
69
|
+
chop chop! concat count crypt delete delete! downcase
|
70
|
+
downcase! dump each each_byte each_line empty? end_with? gsub
|
71
|
+
gsub! hash hex include? index insert intern iseuc issjis
|
72
|
+
isutf8 kconv length ljust lstrip lstrip! match next next! oct
|
73
|
+
reverse reverse! rindex rjust rstrip rstrip! scan size slice
|
74
|
+
slice! split squeeze squeeze! start_with? strip strip! sub
|
75
|
+
sub! succ succ! sum swapcase swapcase! to_f to_i to_str to_sym
|
76
|
+
to_xs toeuc tojis tosjis toutf16 toutf8 tr tr! tr_s tr_s!
|
77
|
+
upcase upcase! upto),
|
78
|
+
|
79
|
+
'Symbol' => %w(to_i to_int),
|
80
|
+
|
81
|
+
'Time' => %w(_dump asctime ctime day dst? getgm getlocal getutc gmt?
|
82
|
+
gmt_offset gmtime gmtoff hash hour httpdate isdst iso8601
|
83
|
+
localtime mday min minus_without_duration mon month
|
84
|
+
plus_without_duration rfc2822 rfc822 sec strftime succ to_date
|
85
|
+
to_datetime to_f to_i tv_sec tv_usec usec utc utc? utc_offset
|
86
|
+
wday xmlschema yday year zone to_formatted_s),
|
87
|
+
|
88
|
+
'Date' => %w(ajd amjd asctime ctime cwday cweek cwyear day day_fraction
|
89
|
+
default_inspect downto england gregorian gregorian? hash italy
|
90
|
+
jd julian julian? ld leap? mday minus_without_duration mjd mon
|
91
|
+
month new_start newsg next ns? os? plus_without_duration sg
|
92
|
+
start step strftime succ upto wday yday year),
|
93
|
+
|
94
|
+
'DateTime' => %w(hour, min, new_offset, newof, of, offset, sec,
|
95
|
+
sec_fraction, strftime, to_datetime_default_s, to_json, zone),
|
96
|
+
|
97
|
+
'NilClass' => %w(blank? duplicable? to_f to_i),
|
98
|
+
|
99
|
+
'FalseClass' => %w(blank? duplicable?),
|
100
|
+
|
101
|
+
'TrueClass' => %w(blank? duplicable?)
|
102
|
+
|
103
|
+
}
|
104
|
+
end
|