ruby_list_comprehension 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ruby_list_comprehension.rb +64 -68
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2d35273a3ae0a52a219848adb715d96ca5f13dbd0eb500c4ae80ea2cc151977
4
- data.tar.gz: b5ddeb3771d13d9c314f0bc7588db1d918b79396fe32e4b27b87fa86812d8a53
3
+ metadata.gz: c98ac6df6bb53e83ad1eafbb630dae2bdfd4f751ae3980d8cd3dfeabe0f38cbe
4
+ data.tar.gz: 0c3bf63664daf1987027bcb719b5e9fe3cbf1fa816d151f9a0881ec803710acc
5
5
  SHA512:
6
- metadata.gz: 302c90d601a6affe56d8a06567ec6ea3071f216e274131f7184185a082e77ebd7b6a23752feb6222a602fbb84828ed6fcbc1511c381728ddf86af26d0c4d4156
7
- data.tar.gz: 8a60c0e66d4e6defc8a3b728cc2b4a656ac8c12237a14a96d51447b440049bd0234c4b07fcd29b68fc0cfb5ae8519a9f301d69ef95202a1bde00b73b4c883d8a
6
+ metadata.gz: 2622a26bde77b8f3ee314a52db76e2650d0020a9c18ca4a38c147a98a7aeb4762af5a52e8878baa33a1677764525a62dbb321a6de080b8133029dd901f9e4335
7
+ data.tar.gz: 300dd50e3138851e1ad102dd1551fb37cc7604f970f1162c4de0f36d4146c66be18a397b443463cc7e4a9963d1fa6796736c7a9d6953888d9d9c930ecaf754d7
@@ -1,44 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ListComprehension
4
- attr_accessor :cache, :caching
5
- attr_reader :c, :version, :op
4
+ attr_accessor :cache, :caching, :mappable, :filterable, :iterable, :var, :list
5
+ attr_reader :c, :version, :op, :cache_count
6
6
 
7
- def [](*args)
8
- c[*args]
7
+ def [](list_comp)
8
+ c[list_comp]
9
9
  end
10
10
 
11
11
  def initialize
12
12
  @cache = {}
13
- @op = nil
13
+ @count = 0
14
+ @op = {}
15
+ @cache_count = 0
14
16
  @caching = true
15
17
  @version = RUBY_VERSION
16
- @c = lambda { |x| # check for cached results
17
- return [] if x == ''
18
- x.concat(' end')if x[-3..-1] != 'end'
19
- return @cache[x] if @caching && @cache[x]
20
-
21
- # p "cached: #{@cache[arr].to_s}" if @cache[arr]
18
+ @c = lambda { |list| # check for cached results
19
+ return [] unless list.is_a? String
20
+
21
+ @list = list.strip
22
+ case list
23
+ when '{}' then return [{}]
24
+ when '[]' then return [[]]
25
+ when '' then return []
26
+ else list += ' end' unless list.include?('end')
27
+ end
28
+ raise 'syntax error in list comprehension' if list.length < 10
22
29
 
23
- y = x[0..-1] # copy of original call
24
- z = y[0..-1] # copy of original call
25
- return [] if x.empty? || x == '' || x.nil? || eval(z[3]) == '[]'
26
- raise 'syntax error in list comprehension' if x.length < 10
30
+ if @caching && @cache[list]
31
+ @cache_count += 1
32
+ return @cache[list]
33
+ end
27
34
 
28
- raise 'please use "x" as block parameter name for now' if x[3..5] != ' x '
35
+ copy1 = list[0..-1]
36
+ arr = list.split
37
+ @var = arr[1]
29
38
 
30
- arr = x.split
31
- if !arr.include?('do')
32
- arr.insert(5, 'do')
33
- end
34
39
  # replace initial semicolon with do if needed for parser
35
- if arr[3][-1] == ';' || arr[4][0] == ';' || arr[5][0] == ';' && !arr.include?('do')
36
- arr = x.to_s.sub(';', ' do ').split
40
+ if arr[3..-1].any?{|x|x.include?(';')} && !arr.include?('do')
41
+ arr = list.to_s.sub(';', ' do ').split
37
42
  end
43
+ arr.insert(-2, 'do') if arr.none?{|x|x.include?('do')} && arr.none?{|x|x.include?('do')}
44
+ # p arr
38
45
 
39
46
  # pre-eval to check for invalid syntax
40
47
  begin
41
- res = instance_eval(x)
48
+ # p arr.join(' ')
49
+ res = instance_eval(arr.join(' '))
42
50
  return [] if res.nil?
43
51
  rescue SyntaxError => se
44
52
  raise 'incorrect syntax for list comprehension' + "\n" + se.to_s
@@ -46,73 +54,61 @@ class ListComprehension
46
54
 
47
55
  # check for hash to parse csv's
48
56
  iterable = arr[3]
49
- return [{}] if iterable == "{}"
50
-
51
- mdata = y[3...y.rindex('do')].match(/{.+[=>:].+}/)
52
- if mdata && mdata[0].include?(';')
53
- # p 'hi'
54
- iterable = mdata[0].split(';')[0]
55
- # p iterable
56
- # p arr.insert(5, "do")
57
- end
58
- if mdata
59
- if instance_eval(mdata[0]).is_a? Hash
60
- iterable = mdata[0]
61
- p mdata[0]
62
- p iterable
63
- p arr
64
-
65
- if iterable[-1] == ';'
66
- iterable = iterable[0..-1]
57
+ return [{}] if iterable == '{}'
58
+ m_data = copy1[3...copy1.rindex('do')].match(/({.+[=>:].+})/)
59
+ if m_data
60
+ first_hash = m_data[0].split(';')[0]
61
+ if arr.index(first_hash) == 3
62
+ if instance_eval(m_data[0].split(';')[0]).is_a? Hash
63
+ iterable = m_data[0].split(';')[0]
67
64
  end
68
65
  end
69
66
  end
70
-
67
+ @iterable = instance_eval(iterable)
71
68
  if_condition = arr.include?('if') ? arr[arr.index('if') + 1...-1] : ['true']
72
69
  map_condition = arr[arr.index('do') + 1...(arr.index('if') || arr.index('end'))]
73
-
74
- if (map_condition == [arr[1]]) && (if_condition == ['true'])
75
- @op = "each"
76
- res = instance_eval(iterable)
77
- return res.is_a?(Array) ? res : [res]
78
- end
70
+ @filterable = if_condition.join(' ')
71
+ @mappable = map_condition.join(' ')
72
+ # p @mappable
73
+ ### list_comprehension identity currently uses for(each) as if normal ruby
74
+ # p @filterable
75
+ # p @mappable
76
+ return *@iterable if (@mappable == @var || @mappable == '') && (@filterable == 'true' || @filterable == @var)
79
77
 
80
78
  # define a method to handle the transformation to list_comp
81
79
  self.class.send(:define_method, 'lc') do |arr|
82
- if map_condition.include?(arr[1])
83
- @op = 'filter'
84
- return instance_eval(iterable).filter do |x|
85
- instance_eval(if_condition.join(' '))
86
- end
80
+
81
+ if @mappable == @var
82
+ @op[@count] = 'filter'
83
+ @count += 1
84
+ return @iterable.filter { |x| instance_eval(@filterable.gsub(@var, x.to_s))}
87
85
  end
88
86
 
89
- if if_condition.include?('true' || 'x') || if_condition
90
- @op = 'map'
91
- return instance_eval(iterable).map do |x|
92
- instance_eval(map_condition.join(' '))
93
- end
87
+ if @filterable == 'true' || @filterable == @var
88
+ @op[@count] = 'map'
89
+ @count += 1
90
+ return @iterable.map { |x| instance_eval(@mappable.gsub(@var, x.to_s))}
94
91
  end
95
92
 
93
+ filter_map_condition_args = "#@mappable if #@filterable"
96
94
  # check Ruby Version stored in @version
97
95
  if @version >= '2.7.0'
98
- @op = 'filter_map'
99
- return instance_eval(iterable).filter_map do |x|
100
- instance_eval(map_condition.join(' ')) if instance_eval(if_condition.join(' '))
101
- end
96
+ @op[@count] = 'filter_map'
97
+ @count += 1
98
+ return @iterable.filter_map { |x| instance_eval(filter_map_condition_args.gsub(@var, x.to_s)) }
102
99
  else
103
- @op = 'map&compact'
104
- return instance_eval(iterable).map do |x|
105
- instance_eval(map_condition.join(' ')) if instance_eval(if_condition.join(' '))
106
- end.compact!
100
+ @op[@count] = 'map&compact'
101
+ @count += 1
102
+ @iterable.map { |x| instance_eval(filter_map_condition_args.gsub!(@var, x.to_s)) }.compact!
107
103
  end
108
104
  end
109
105
  list_comp = lc(arr)
110
106
  unless list_comp.is_a?(Array) || list_comp.is_a?(Hash)
111
107
  list_comp = [list_comp]
112
108
  end
113
-
114
109
  list_comp = list_comp == [nil] ? [] : list_comp
115
- @cache[arr] = list_comp if @caching
110
+ # p @op
111
+ @cache[list] = list_comp if @caching
116
112
  }
117
113
  end
118
114
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_list_comprehension
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Michael
@@ -43,7 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
43
43
  - !ruby/object:Gem::Version
44
44
  version: '0'
45
45
  requirements: []
46
- rubygems_version: 3.0.3
46
+ rubygems_version: 3.0.6
47
47
  signing_key:
48
48
  specification_version: 4
49
49
  summary: Ruby List Comprehension