Module: RubyLess::SafeClass
- Defined in:
- lib/ruby_less/safe_class.rb
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
- .all_safe_methods ⇒ Object
-
.included(base) ⇒ Object
ClassMethods.
- .literal_class_for(klass) ⇒ Object
- .safe_literal_class(hash) ⇒ Object
-
.safe_method_for(klass, methods_hash) ⇒ Object
Declare a safe method for a given class ( same as #safe_method).
-
.safe_method_type_for(klass, signature) ⇒ Object
Return method type (options) if the given signature is a safe method for the class.
-
.safe_method_type_for_column(col, is_property = false) ⇒ Object
Return a safe type from a column.
-
.safe_methods_for(klass) ⇒ Object
List of safe methods for a specific class.
Instance Method Summary collapse
-
#safe_eval(code) ⇒ Object
Evaluate a RubyLess expression.
-
#safe_eval_string(code) ⇒ Object
Evaluate a RubyLess expression.
-
#safe_method_type(signature, receiver = nil) ⇒ Object
Return the type if the given signature corresponds to a safe method for the object’s class.
-
#safe_send(method) ⇒ Object
Safe dynamic method dispatching when the method is not known during compile time.
Class Method Details
.all_safe_methods ⇒ Object
54 55 56 |
# File 'lib/ruby_less/safe_class.rb', line 54 def self.all_safe_methods @@_safe_methods end |
.included(base) ⇒ Object
ClassMethods
198 199 200 |
# File 'lib/ruby_less/safe_class.rb', line 198 def self.included(base) base.extend ClassMethods end |
.literal_class_for(klass) ⇒ Object
46 47 48 |
# File 'lib/ruby_less/safe_class.rb', line 46 def self.literal_class_for(klass) @@_safe_literal_classes[klass] end |
.safe_literal_class(hash) ⇒ Object
50 51 52 |
# File 'lib/ruby_less/safe_class.rb', line 50 def self.safe_literal_class(hash) @@_safe_literal_classes.merge!(hash) end |
.safe_method_for(klass, methods_hash) ⇒ Object
Declare a safe method for a given class ( same as #safe_method)
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 |
# File 'lib/ruby_less/safe_class.rb', line 59 def self.safe_method_for(klass, methods_hash) # This is why defining new safe methods during runtime is BAD. @@_safe_methods_parsed = {} # rebuild all cache defaults = methods_hash.delete(:defaults) || {} list = (@@_safe_methods[klass] ||= {}) methods_hash.each do |signature, type| signature, hash_args = build_signature(signature) type = {:class => type} unless type.kind_of?(Hash) type = defaults.merge(type) type[:method] = type[:method] ? type[:method].to_s : signature.first.to_s if hash_args type[:hash_args] = hash_args list[signature] = type if hash_args.last.kind_of?(Hash) # Also build signature without last hash. This enables the common idiom # method(arg, arg, opts = {}) list[signature[0..-2]] = type.dup end else list[signature] = type end end end |
.safe_method_type_for(klass, signature) ⇒ Object
Return method type (options) if the given signature is a safe method for the class.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ruby_less/safe_class.rb', line 13 def self.safe_method_type_for(klass, signature) if klass.kind_of?(Array) safe_method_type_for(Array, signature) elsif klass.kind_of?(Hash) nil # literal hash resolved in processor klass = Hash else # Signature might be ['name', {:mode => String, :type => Number}]. # build signature arguments # Replace all hashes in signature by Hash class and check for arguments signature_args = [] signature = signature.map do |s| if s.kind_of?(Hash) signature_args << s Hash else signature_args << nil s end end # Find safe method in all ancestry klass.ancestors.each do |ancestor| # FIXME: find a way to optimize this search ! if type = safe_method_with_hash_args(ancestor, signature, signature_args) return type end end nil end end |
.safe_method_type_for_column(col, is_property = false) ⇒ Object
Return a safe type from a column
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/ruby_less/safe_class.rb', line 86 def self.safe_method_type_for_column(col, is_property = false) opts = {} opts[:nil] = col.default.nil? if col.number? opts[:class] = Number elsif col.text? opts[:class] = String else opts[:class] = col.klass end if is_property opts[:method] = "prop['#{col.name.gsub("'",'')}']" else opts[:method] = col.name end opts end |
.safe_methods_for(klass) ⇒ Object
List of safe methods for a specific class.
8 9 10 |
# File 'lib/ruby_less/safe_class.rb', line 8 def self.safe_methods_for(klass) @@_safe_methods_parsed[klass] ||= build_safe_methods_list(klass) end |
Instance Method Details
#safe_eval(code) ⇒ Object
Evaluate a RubyLess expression. This is just like ‘eval’ but with safe method checking and typing.
217 218 219 220 |
# File 'lib/ruby_less/safe_class.rb', line 217 def safe_eval(code) ruby = RubyLessProcessor.translate(self, code) eval(ruby) end |
#safe_eval_string(code) ⇒ Object
Evaluate a RubyLess expression. This is just like ‘eval’ but with safe method checking and typing.
223 224 225 226 |
# File 'lib/ruby_less/safe_class.rb', line 223 def safe_eval_string(code) ruby = RubyLess.translate_string(self, code) eval(ruby) end |
#safe_method_type(signature, receiver = nil) ⇒ Object
Return the type if the given signature corresponds to a safe method for the object’s class.
203 204 205 206 207 |
# File 'lib/ruby_less/safe_class.rb', line 203 def safe_method_type(signature, receiver = nil) if type = SafeClass.safe_method_type_for(self.class, signature) type[:class].kind_of?(Symbol) ? self.send(type[:class], signature) : type end end |
#safe_send(method) ⇒ Object
Safe dynamic method dispatching when the method is not known during compile time. Currently this only works for methods without arguments.
211 212 213 214 |
# File 'lib/ruby_less/safe_class.rb', line 211 def safe_send(method) return nil unless type = self.class.safe_method_type([method]) self.send(type[:method]) end |