rubyless 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.3.3 2009-10-26
2
+
3
+ * 1 minor enhancement
4
+ * added support for symbols (only used with helper)
5
+
1
6
  == 0.3.2 2009-10-15
2
7
 
3
8
  * 1 minor enhancement
data/lib/processor.rb CHANGED
@@ -210,8 +210,8 @@ module RubyLess
210
210
 
211
211
  def get_method(signature, receiver, is_method = true)
212
212
  res = receiver.respond_to?(:safe_method_type) ? receiver.safe_method_type(signature) : SafeClass.safe_method_type_for(receiver, signature)
213
- res = res.call(@helper) if res.kind_of?(Proc)
214
- res
213
+ res = res.call(@helper, signature) if res.kind_of?(Proc)
214
+ res.kind_of?(Symbol) ? nil : res # Symbols not allowed here (should be resolved in receiver.safe_method_type)
215
215
  end
216
216
  end
217
217
  end
data/lib/rubyless.rb CHANGED
@@ -6,7 +6,7 @@ require 'processor'
6
6
  =begin rdoc
7
7
  =end
8
8
  module RubyLess
9
- VERSION = '0.3.2'
9
+ VERSION = '0.3.3'
10
10
 
11
11
  def self.translate(string, helper)
12
12
  RubyLessProcessor.translate(string, helper)
data/lib/safe_class.rb CHANGED
@@ -10,11 +10,7 @@ module RubyLess
10
10
 
11
11
  # Return method type (options) if the given signature is a safe method for the class.
12
12
  def self.safe_method_type_for(klass, signature)
13
- if res = safe_methods_for(klass)[signature]
14
- res.dup
15
- else
16
- nil
17
- end
13
+ safe_methods_for(klass)[signature]
18
14
  end
19
15
 
20
16
  # Declare a safe method for a given class
@@ -65,7 +61,7 @@ module RubyLess
65
61
  if v.kind_of?(Hash)
66
62
  v = defaults.merge(v)
67
63
  v[:method] = v[:method] ? v[:method].to_s : k.first.to_s
68
- elsif v.kind_of?(Proc)
64
+ elsif v.kind_of?(Proc) || v.kind_of?(Symbol)
69
65
  # cannot merge defaults
70
66
  else
71
67
  v = defaults.merge(:class => v, :method => k.first.to_s)
@@ -106,22 +102,21 @@ module RubyLess
106
102
  SafeClass.safe_methods_for(self)
107
103
  end
108
104
 
109
- # Return true if the given signature corresponds to a safe method for the class.
105
+ # Return the type if the given signature corresponds to a safe method for the class.
110
106
  def self.safe_method_type(signature)
111
- if res = SafeClass.safe_method_type_for(self, signature)
112
- res.dup # TODO: replace by freeze
113
- else
114
- nil
115
- end
116
- end
117
-
118
- # Return the method type (options) if the given signature is a safe method for the class.
119
- def safe_method_type(signature)
120
- self.class.safe_method_type(signature)
107
+ SafeClass.safe_method_type_for(self, signature)
121
108
  end
122
109
  end # base.class_eval
123
110
  end # included
124
111
 
112
+
113
+ # Return the type if the given signature corresponds to a safe method for the object's class.
114
+ def safe_method_type(signature)
115
+ if type = self.class.safe_method_type(signature)
116
+ type.kind_of?(Symbol) ? self.send(type, signature) : type
117
+ end
118
+ end
119
+
125
120
  # Safe attribute reader used when 'safe_readable?' could not be called because the class
126
121
  # is not known during compile time.
127
122
  def safe_read(key)
@@ -135,12 +130,14 @@ module RubyLess
135
130
  (@@_safe_methods[klass] || {}).map do |signature, return_value|
136
131
  if return_value.kind_of?(Hash)
137
132
  return_value[:class] = parse_class(return_value[:class])
138
- elsif !return_value.kind_of?(Proc)
133
+ elsif return_value.kind_of?(Proc) || return_value.kind_of?(Symbol)
134
+ # keep
135
+ else
139
136
  return_value = {:class => return_value}
140
137
  end
141
138
  method = signature.shift
142
139
  signature = [method] + signature.map {|e| parse_class(e)}
143
- list[signature] = return_value
140
+ list[signature] = return_value.freeze
144
141
  end
145
142
  list
146
143
  end
data/rubyless.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{rubyless}
5
- s.version = "0.3.1"
5
+ s.version = "0.3.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Gaspard Bucher"]
9
- s.date = %q{2009-10-03}
9
+ s.date = %q{2009-10-26}
10
10
  s.description = %q{RubyLess is an interpreter for "safe ruby". The idea is to transform some "unsafe" ruby code into safe, type checked
11
11
  ruby, eventually rewriting some variables or methods.}
12
12
  s.email = %q{gaspard@teti.ch}
@@ -86,4 +86,8 @@ multi_arg_method_arguments_can_be_nil_same_condition:
86
86
 
87
87
  literal_argument_for_method:
88
88
  src: "vowel_count('ruby')"
89
- res: "2"
89
+ res: "2"
90
+
91
+ safe_method_defined_as_symbol:
92
+ src: "foo"
93
+ tem: "contextual_foo"
@@ -10,7 +10,7 @@ zero_div:
10
10
  src: "1/(id-10)"
11
11
  tem: "(1/(var1.zip-10) rescue nil)"
12
12
  res: ""
13
-
13
+
14
14
  looping:
15
15
  src: "while(true) do puts 'flood' end"
16
16
  res: 'Bug! Unknown node-type :while to RubyLess::RubyLessProcessor'
@@ -29,4 +29,8 @@ number_argument:
29
29
 
30
30
  string_argument:
31
31
  src: "dictionary[spouse.name]"
32
- res: "'get_dict' does not respond to '[](String)'."
32
+ res: "'get_dict' does not respond to '[](String)'."
33
+
34
+ symbol_type_not_used_out_of_helper:
35
+ src: "node.foo"
36
+ res: "'var1' does not respond to 'foo()'."
@@ -12,28 +12,33 @@ class SimpleHelper < Test::Unit::TestCase
12
12
  include RubyLess::SafeClass
13
13
  safe_method :prev => {:class => Dummy, :method => 'previous'}
14
14
  safe_method :main => {:class => Dummy, :method => '@node'}
15
- safe_method :node => lambda {|h| {:class => h.context[:node_class], :method => h.context[:node]}}
15
+ safe_method :node => lambda {|h, s| {:class => h.context[:node_class], :method => h.context[:node]}}
16
16
  safe_method :now => {:class => Time, :method => "Time.now"}
17
17
  safe_method :birth => {:class => Time, :method => "Date.parse('2009-06-02 18:44')"}
18
18
  safe_method 'dictionary' => {:class => StringDictionary, :method => 'get_dict'}
19
19
  safe_method [:vowel_count, String] => Number
20
20
  safe_method [:log_info, Dummy, String] => String
21
+ safe_method :foo => :contextual_method, :bar => :contextual_method
21
22
  safe_method_for String, [:==, String] => Boolean
22
23
  safe_method_for String, [:to_s] => String
23
24
  safe_method_for Time, [:strftime, String] => String
24
25
 
25
26
  # Example to dynamically rewrite method calls during compilation
26
27
  def safe_method_type(signature)
27
- unless res = self.class.safe_method_type(signature)
28
+ unless res = super
28
29
  # try to execute method in the current var "var.method"
29
30
  if res = context[:node_class].safe_method_type(signature)
30
- res = res.call(self) if res.kind_of?(Proc)
31
- res[:method] = "#{context[:node]}.#{res[:method] || signature[0]}"
31
+ res = res.call(self, signature) if res.kind_of?(Proc)
32
+ res = res.merge(:method => "#{context[:node]}.#{res[:method] || signature[0]}")
32
33
  end
33
34
  end
34
35
  res
35
36
  end
36
37
 
38
+ def contextual_method(signature)
39
+ {:method => "contextual_#{signature[0]}", :class => String}
40
+ end
41
+
37
42
  def var1
38
43
  Dummy.new
39
44
  end
@@ -75,7 +80,7 @@ class SimpleHelper < Test::Unit::TestCase
75
80
  rescue => err
76
81
  # puts "\n\n#{err.message}"
77
82
  # puts err.backtrace
78
- err.message
83
+ err.message
79
84
  end
80
85
 
81
86
  yt_make
@@ -3,37 +3,38 @@ require File.dirname(__FILE__) + '/active_record_mock'
3
3
  class Dummy < RubyLess::ActiveRecordMock
4
4
  attr_reader :name
5
5
  include RubyLess::SafeClass
6
-
6
+
7
7
  safe_method [:ancestor?, Dummy] => Boolean
8
8
  safe_method :parent => {:class => 'Dummy', :special_option => 'foobar'},
9
9
  :children => ['Dummy'],
10
10
  :project => 'Dummy',
11
11
  :id => {:class => Number, :method => :zip},
12
- :name => String
12
+ :name => String,
13
+ :foo => :bar
13
14
  safe_method :defaults => {:nil => true},
14
15
  :spouse => 'Dummy',
15
16
  :husband => {:class => 'Dummy'}
16
-
17
+
17
18
  safe_attribute :age, :friend_id, :log_at, :format
18
-
19
+
19
20
  def initialize(name = 'dummy')
20
21
  @name = name
21
22
  end
22
-
23
+
23
24
  # This method returns pseudo-nil and does not need to be declared with :nil => true
24
25
  def project
25
26
  Dummy.new('project')
26
27
  end
27
-
28
+
28
29
  # This method can return nil and must be declared with :nil => true
29
30
  def spouse
30
31
  nil
31
32
  end
32
-
33
+
33
34
  def husband
34
35
  nil
35
36
  end
36
-
37
+
37
38
  def zip
38
39
  10
39
40
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gaspard Bucher
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-15 00:00:00 +02:00
12
+ date: 2009-10-26 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency