flyerhzm / rails_best_practices

a code metric tool for rails projects
http://rails-bestpractices.com
MIT License
4.17k stars 277 forks source link

Support for lambda within lambda #107

Open pboling opened 12 years ago

pboling commented 12 years ago

Using latest code from master@9d6518fcca (add brace_block support in routes) I get an error processing a module (mixing) I have for adding date range capabilities to other code.

The Error

∴ ./bin/rails_best_practices ~/RubyMineProjects/my_rails_app/
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 9oooooooooooooooooooooooooooooooooooooooooooooooooooooo                                             | ETA:   0:00:06
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 9
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: method_add_arg
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: method_add_arg
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 9
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: array
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: stmts_add
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 9
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: method_add_block
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: assoc_new
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: assoclist_from_args
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: hash
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: assign
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: assign
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: assign
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: assign
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: aref
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: stmts_add
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 3
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 3
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: aref
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: assign
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: module
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: sclass
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: 1
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: module
find error in file: /Users/pboling/RubyMineProjects/my_rails_app/app/mixins/date_range.rb line: stmts_add
/Users/pboling/RubyMineProjects/railsbp-rails_best_practices-9d6518f/lib/rails_best_practices/core/check.rb:327:in `mark_used': undefined method `sexp_type' for :call:Symbol (NoMethodError)
  from /Users/pboling/RubyMineProjects/railsbp-rails_best_practices-9d6518f/lib/rails_best_practices/core/check.rb:245:in `block (2 levels) in included'
  from /Users/pboling/RubyMineProjects/railsbp-rails_best_practices-9d6518f/lib/rails_best_practices/core/check.rb:51:in `instance_exec'
  from /Users/pboling/RubyMineProjects/railsbp-rails_best_practices-9d6518f/lib/rails_best_practices/core/check.rb:51:in `block in node_start'
  from /Users/pboling/RubyMineProjects/railsbp-rails_best_practices-9d6518f/lib/rails_best_practices/core/check.rb:50:in `each'
  from /Users/pboling/RubyMineProjects/railsbp-rails_best_practices-9d6518f/lib/rails_best_practices/core/check.rb:50:in `node_start'
  from (eval):6:in `block in review'
  from (eval):4:in `each'
  from (eval):4:in `review'
  from /Users/pboling/RubyMineProjects/railsbp-rails_best_practices-9d6518f/lib/rails_best_practices/core_ext/sexp.rb:16:in `review'
  from (eval):12:in `block in review'
  from (eval):10:in `each'
  from (eval):10:in `review'

The Code

1 module DateRange
2   #This constant is used to add constraints into routes, and to validate the parameter passed to summary_ranges, date_filter_options
3   RANGES = lambda {
4     date_from_time = lambda do |src_time|
5       Time.mktime(src_time.year, src_time.month, src_time.day)
6     end
7 
8     last_month = {
9       'range' => lambda { [date_from_time.(31.days.ago), date_from_time.(Time.now)] },
10       'value' => 'last_month',
11       'label' => 'Last month'}
12 
13     last_3_months = {
14       'range' => lambda { [date_from_time.(91.days.ago), date_from_time.(Time.now)] },
15       'value' => 'last_3_months',
16       'label' => 'Last 3 months'}
17 
18     year_to_date = {
19       'range' => lambda { [date_from_time.(Time.now.beginning_of_year), date_from_time.(Time.now)] },
20       'value' => 'year_to_date',
21       'label' => 'This year'}
22 
23     since_inception = {
24       'range' => lambda { [date_from_time.(Date.parse('2011-01-01')), date_from_time.(Time.now)] },
25       'value' => 'since_inception',
26       'label' => 'Since inception'}
27 
28     Hash[[last_month, last_3_months, year_to_date, since_inception].collect { |x| [x['value'], x] }]
29   }[]
30 
31   module Methods
32     def summary_ranges(date_range)
33       raise "invalid date_range" unless RANGES.has_key?(date_range)
34 
35       RANGES[date_range]['range'][]
36     end
37 
38     def date_filter_options(date_range)
39       raise "invalid date_range" unless RANGES.has_key?(date_range)
40 
41       RANGES.values.collect do |range|
42         option = {'value' => range['value'], 'label' => range['label']}
43         range['value'] == date_range ? {'selected' => true}.reverse_merge(option) : option
44       end
45     end
46   end
47 
48   class << self
49     def included(target)
50       target.class_eval do
51         extend ActiveSupport::Memoizable
52         include Methods
53         memoize :summary_ranges, :date_filter_options
54       end
55     end
56   end
57 end
flyerhzm commented 12 years ago

it is fixed in HEAD code

pboling commented 12 years ago

Thanks!

pboling commented 12 years ago

Please reopen this ticket.

On Ruby 1.9.3-p194, ruby_best_practices version 1.9.1, I am still getting the same error on the same line (line 9 above).

You may have solved for lambdas, but what I have here are lambdas within lambdas:

Snippet from previous comment to highlight the failure:

RANGES = lambda {
     date_from_time = lambda do |src_time|
       Time.mktime(src_time.year, src_time.month, src_time.day)
     end

     last_month = {
       'range' => lambda { [date_from_time.(31.days.ago), date_from_time.(Time.now)] },
       'value' => 'last_month',
       'label' => 'Last month'}
 }[]

It is dying on this line, which is a lambda nested within the outer lambda:

range' => lambda { [date_from_time.(31.days.ago), date_from_time.(Time.now)] },