grumlin 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0f0edafd4d46b787eb3f8e0ec4032948bdb4de865e4de3199606fb470dc16ef3
4
- data.tar.gz: f23ba59dfb18dabe70fc860c38ea4c1777214b4a37e04771b24210d90f449612
3
+ metadata.gz: b01ddca4a13e70f6ab86875cd635655ebec77e877f374b0df9c8021f61ae7753
4
+ data.tar.gz: c25ccd742c5c40ba797f92fe39176cf2605d485506e56a1a1e8852bbbc11ab0b
5
5
  SHA512:
6
- metadata.gz: 4629a25995953c6617a45721d7082baee59b76425636f6a4536308220bae3e7cb72b571317102339b1888c0e430dbe73320c12f44518940f45c67db829a9a265
7
- data.tar.gz: fae1a56f95150f82da47a886da5e4b4a7ab0f725f66e68af61f6456c9a2f1af2cefc580ebf793cba612f0ceeda0b782361476a38511019062cc1534ad98fdb3c
6
+ metadata.gz: '042067879c5ae297f5d3a06f2f0a7302cccb5dc0e362fcdb15820f74e8aec6b1d9f5cd085bcfdbfe3d2f671fe8cae24b8da38c03a89e4a645c42a31d60218005'
7
+ data.tar.gz: b740805e7ab51fc7d45aeb0a1cc11062778561439a51395de1cdf1bd771a8745768c17e4e0b2db4daf2382ba6008f898e469c3f474d4738775c72a99c47cdd75
data/Gemfile CHANGED
@@ -14,5 +14,6 @@ gem "solargraph"
14
14
  gem "async-rspec"
15
15
  gem "factory_bot"
16
16
  gem "overcommit"
17
+ gem "rake"
17
18
  gem "rspec"
18
19
  gem "simplecov"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- grumlin (0.11.0)
4
+ grumlin (0.12.0)
5
5
  async-pool (~> 0.3)
6
6
  async-websocket (~> 0.19)
7
7
  oj (~> 3.12)
@@ -83,6 +83,7 @@ GEM
83
83
  protocol-http1 (~> 0.2)
84
84
  racc (1.5.2)
85
85
  rainbow (3.0.0)
86
+ rake (13.0.3)
86
87
  regexp_parser (2.1.1)
87
88
  reverse_markdown (2.0.0)
88
89
  nokogiri
@@ -161,6 +162,7 @@ DEPENDENCIES
161
162
  grumlin!
162
163
  nokogiri
163
164
  overcommit
165
+ rake
164
166
  rspec
165
167
  rubocop
166
168
  rubocop-performance
data/README.md CHANGED
@@ -1,10 +1,30 @@
1
1
  # Grumlin
2
2
 
3
- [Gremlin](https://tinkerpop.apache.org/gremlin.html) query language DSL for Ruby
3
+ [![Ruby](https://github.com/zhulik/grumlin/actions/workflows/main.yml/badge.svg)](https://github.com/zhulik/grumlin/actions/workflows/main.yml)
4
+ [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
5
+ [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/)
4
6
 
5
- **In development. Nothing to write here yet. If you are really interested, check out the source code and the specs.**
7
+ Grumlin is a [Gremlin](https://tinkerpop.apache.org/gremlin.html) graph traversal language DSL and client for Ruby.
8
+ Suitable for and tested with [gremlin-server](http://tinkerpop.apache.org/) and [AWS Neptune](https://aws.amazon.com/neptune/).
6
9
 
7
- ## Installation
10
+ **Important**: Grumlin and it's author are not affiliated with The Apache Software Foundation which develops gremlin
11
+ and gremlin-server.
12
+
13
+ **Important**: Grumlin is based on the [async stack](https://github.com/socketry/async) and utilizes
14
+ [async-websocket](https://github.com/socketry/async-websocket). Code using grumlin must be executed in an async
15
+ event loop.
16
+
17
+ **Warning:** Grumlin is in development, but ready for simple use cases
18
+
19
+ ## Table of contents
20
+ - [Install](#install)
21
+ - [Usage](#usage)
22
+ - [Development](#development)
23
+ - [Contributing](#contributing)
24
+ - [License](#license)
25
+ - [Code Of Conduct](#code-of-conduct)
26
+
27
+ ## Install
8
28
 
9
29
  Add this line to your application's Gemfile:
10
30
 
@@ -22,17 +42,77 @@ Or install it yourself as:
22
42
 
23
43
  ## Usage
24
44
 
25
- TODO: Write usage instructions here
45
+ ### Configuration
46
+ ```ruby
47
+ Grumlin.configure do |config|
48
+ config.url = "ws://localhost:8182/gremlin"
49
+ end
50
+ ```
51
+
52
+ ### Traversing graphs
53
+
54
+ **Warning:** Not all steps and tools described in the standard are supported
55
+
56
+ #### Sugar
57
+
58
+ Grumlin provides an easy to use module called `Grumlin::Sugar`. Once included in your class it injects some useful
59
+ constants and methods turning your class into an entrypoint for traversals.
60
+
61
+ ```ruby
62
+ class MyRepository
63
+ include Grumlin::Sugar
64
+
65
+ def nodes(property1:, property2:)
66
+ g.V()
67
+ .has(T.label, "node")
68
+ .has(:property1, property1)
69
+ .has(:property2, property2)
70
+ .order.by(:property3, Order.asc).limit(10)
71
+ .toList
72
+ end
73
+ end
74
+ ```
75
+
76
+ #### Testing
77
+
78
+ Grumlin provides a couple of helpers to simplify testing code written with it.
79
+
80
+ ##### RSpec
81
+
82
+ Make sure you have [async-rspec](https://github.com/socketry/async-rspec) installed.
83
+
84
+ `spec_helper.rb` or `rails_helper.rb`:
85
+ ```ruby
86
+ require 'async/rspec'
87
+ require require "grumlin/test/rspec"
88
+ ...
89
+ config.include_context(Async::RSpec::Reactor) # Runs async reactor
90
+ config.include_context(Grumlin::Test::RSpec::GremlinContext) # Injects sugar and makes sure client is closed after every test
91
+ config.include_context(Grumlin::Test::RSpec::DBCleanerContext) # Cleans the database before every test
92
+ ...
93
+ ```
94
+
95
+ It is highly recommended to use `Grumlin::Sugar` and not trying to use lower level APIs as they are subject to change.
26
96
 
27
97
  ## Development
28
98
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
99
+ Before running tests make sure you have gremlin-server running on your computer. The simplest way to run it is using
100
+ [docker-compose](https://docs.docker.com/compose/) and provided `docker-compose.yml` and `gremlin_server/Dockerfile`:
101
+
102
+ $ docker-compose up -d gremlin_server
103
+
104
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
105
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
106
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
107
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update
108
+ the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
109
+ push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
110
 
33
111
  ## Contributing
34
112
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/grumlin. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/grumlin/blob/master/CODE_OF_CONDUCT.md).
113
+ Bug reports and pull requests are welcome on GitHub at https://github.com/zhulik/grumlin. This project is intended to
114
+ be a safe, welcoming space for collaboration, and contributors are expected to adhere to the
115
+ [code of conduct](https://github.com/zhulik/grumlin/blob/master/CODE_OF_CONDUCT.md).
36
116
 
37
117
  ## License
38
118
 
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console CHANGED
@@ -19,5 +19,5 @@ Async do
19
19
  rescue StandardError
20
20
  raise
21
21
  ensure
22
- Grumlin.config.default_pool.close
22
+ Grumlin.close
23
23
  end
data/grumlin.gemspec CHANGED
@@ -8,8 +8,12 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Gleb Sinyavskiy"]
9
9
  spec.email = ["zhulik.gleb@gmail.com"]
10
10
 
11
- spec.summary = "Gremlin query language DSL for Ruby."
12
- spec.description = "Gremlin query language DSL for Ruby."
11
+ spec.summary = "Gremlin graph traversal language DSL and client for Ruby."
12
+
13
+ spec.description = <<~DESCRIPTION
14
+ Gremlin graph traversal language DSL and client for Ruby. Suitable and tested with gremlin-server and AWS Neptune.
15
+ DESCRIPTION
16
+
13
17
  spec.homepage = "https://github.com/zhulik/grumlin"
14
18
  spec.license = "MIT"
15
19
  spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
data/lib/async/channel.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Async
4
4
  # Channel is a wrapper around Async::Queue that provides
5
5
  # a protocol and handy tools for passing data, exceptions and closing.
6
- # It is designed to be used with only one publisher and one subscriber
6
+ # It is designed to be used only with one publisher and one subscriber
7
7
  class Channel
8
8
  class ChannelError < StandardError; end
9
9
 
@@ -5,9 +5,9 @@ module Grumlin
5
5
  attr_reader :name, :args, :previous_step
6
6
 
7
7
  # TODO: add other steps
8
- SUPPORTED_STEPS = %w[E V addE addV as by coalesce count dedup drop elementMap emit fold from group groupCount has
9
- hasId hasLabel hasNot in inV label limit not order out outE path project property repeat select
10
- to unfold union valueMap values where].freeze
8
+ SUPPORTED_STEPS = %i[E V addE addV as both by coalesce count dedup drop elementMap emit fold from group groupCount
9
+ has hasId hasLabel hasNot id in inV label limit not order out outE path project property range
10
+ repeat select skip tail to unfold union until valueMap values where with].freeze
11
11
 
12
12
  def initialize(name, *args, previous_step: nil)
13
13
  @name = name
@@ -38,10 +38,10 @@ module Grumlin
38
38
  # depending on the `serialization_method` parameter. I should be either `:to_readable_bytecode` for human readable
39
39
  # representation or `:to_bytecode` for query.
40
40
  def serialize_arg(arg, serialization_method: :to_bytecode)
41
- return arg.send(serialization_method) if arg.respond_to?(:to_bytecode)
41
+ return arg.send(serialization_method) if arg.respond_to?(serialization_method)
42
42
  return arg unless arg.is_a?(AnonymousStep)
43
43
 
44
- arg.args.flatten.each.with_object([arg.name]) do |a, res|
44
+ arg.args.flatten.each.with_object([arg.name.to_s]) do |a, res|
45
45
  res << if a.instance_of?(AnonymousStep)
46
46
  a.bytecode.send(serialization_method)
47
47
  else
data/lib/grumlin/edge.rb CHANGED
@@ -18,7 +18,7 @@ module Grumlin
18
18
  end
19
19
 
20
20
  def inspect
21
- "e[#{@id}][#{@inV}-#{@label}->#{@outV}]"
21
+ "e[#{@id}][#{@outV}-#{@label}->#{@inV}]"
22
22
  end
23
23
  alias to_s inspect
24
24
  end
data/lib/grumlin/path.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Grumlin
4
4
  class Path
5
+ attr_reader :objects
6
+
5
7
  def initialize(path)
6
8
  @labels = Typing.cast(path[:labels])
7
9
  @objects = Typing.cast(path[:objects])
data/lib/grumlin/sugar.rb CHANGED
@@ -3,11 +3,13 @@
3
3
  module Grumlin
4
4
  module Sugar
5
5
  HELPERS = [
6
- Grumlin::U,
7
- Grumlin::T,
8
- Grumlin::P,
9
- Grumlin::Pop,
10
- Grumlin::Order
6
+ Grumlin::Tools::Order,
7
+ Grumlin::Tools::P,
8
+ Grumlin::Tools::Pop,
9
+ Grumlin::Tools::Scope,
10
+ Grumlin::Tools::T,
11
+ Grumlin::Tools::U,
12
+ Grumlin::Tools::WithOptions
11
13
  ].freeze
12
14
 
13
15
  def self.included(base)
@@ -18,7 +20,7 @@ module Grumlin
18
20
  end
19
21
 
20
22
  def __
21
- Grumlin::U
23
+ Grumlin::Tools::U
22
24
  end
23
25
 
24
26
  def g
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Order
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[asc desc].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "Order")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module P
6
+ class << self
7
+ class Predicate < TypedValue
8
+ def initialize(name, args:, arg_type: nil)
9
+ super(type: "P")
10
+ @name = name
11
+ @args = args
12
+ @arg_type = arg_type
13
+ end
14
+
15
+ def value
16
+ @value ||= {
17
+ predicate: @name,
18
+ value: TypedValue.new(type: @arg_type, value: @args).to_bytecode
19
+ }
20
+ end
21
+ end
22
+
23
+ # TODO: support more predicates
24
+ %i[eq neq].each do |predicate|
25
+ define_method predicate do |*args|
26
+ Predicate.new(predicate, args: args[0])
27
+ end
28
+ end
29
+
30
+ %i[within without].each do |predicate|
31
+ define_method predicate do |*args|
32
+ args = if args.count == 1 && args[0].is_a?(Array)
33
+ args[0]
34
+ elsif args.count == 1 && args[0].is_a?(Set)
35
+ args[0].to_a
36
+ else
37
+ args.to_a
38
+ end
39
+ Predicate.new(predicate, args: args, arg_type: "List")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Pop
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[all first last mixed].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "Pop")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Scope
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[local].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "Scope")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module T
6
+ extend Tool
7
+
8
+ SUPPORTED_STEPS = %i[id label].freeze
9
+
10
+ define_steps(SUPPORTED_STEPS, "T")
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module Tool
6
+ def define_steps(steps, tool_name)
7
+ steps.each do |step|
8
+ self.class.define_method step do
9
+ name = "@#{step}"
10
+ return instance_variable_get(name) if instance_variable_defined?(name)
11
+
12
+ instance_variable_set(name, TypedValue.new(type: tool_name, value: step))
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module U
6
+ # TODO: add other start steps
7
+ SUPPORTED_STEPS = %i[V addV count fold has id inV label out outV project repeat timeLimit unfold valueMap
8
+ values].freeze
9
+
10
+ class << self
11
+ SUPPORTED_STEPS.each do |step|
12
+ define_method step do |*args|
13
+ AnonymousStep.new(step, *args)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grumlin
4
+ module Tools
5
+ module WithOptions
6
+ WITH_OPTIONS = {
7
+ tokens: "~tinkerpop.valueMap.tokens",
8
+ none: 0,
9
+ ids: 1,
10
+ labels: 2,
11
+ keys: 4,
12
+ values: 8,
13
+ all: 15,
14
+ indexer: "~tinkerpop.index.indexer",
15
+ list: 0,
16
+ map: 1
17
+ }.freeze
18
+
19
+ class << self
20
+ WITH_OPTIONS.each do |k, v|
21
+ define_method k do
22
+ v
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -2,16 +2,14 @@
2
2
 
3
3
  module Grumlin
4
4
  class Traversal
5
- attr_reader :connection
6
-
7
5
  # TODO: add other start steps
8
- SUPPORTED_START_STEPS = %w[E V addE addV].freeze
6
+ SUPPORTED_STEPS = %i[E V addE addV].freeze
9
7
 
10
8
  def initialize(pool = Grumlin.default_pool)
11
9
  @pool = pool
12
10
  end
13
11
 
14
- SUPPORTED_START_STEPS.each do |step|
12
+ SUPPORTED_STEPS.each do |step|
15
13
  define_method step do |*args|
16
14
  Step.new(@pool, step, *args)
17
15
  end
@@ -13,6 +13,7 @@ module Grumlin
13
13
  "g:Int32" => ->(value) { cast_int(value) },
14
14
  "g:Double" => ->(value) { cast_double(value) },
15
15
  "g:Traverser" => ->(value) { cast(value[:value]) }, # TODO: wtf is bulk?
16
+ "g:Direction" => ->(value) { value },
16
17
  "g:T" => ->(value) { value.to_sym }
17
18
  }.freeze
18
19
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Grumlin
4
- VERSION = "0.11.0"
4
+ VERSION = "0.12.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grumlin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gleb Sinyavskiy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-15 00:00:00.000000000 Z
11
+ date: 2021-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-pool
@@ -66,7 +66,10 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.4'
69
- description: Gremlin query language DSL for Ruby.
69
+ description: 'Gremlin graph traversal language DSL and client for Ruby. Suitable and
70
+ tested with gremlin-server and AWS Neptune.
71
+
72
+ '
70
73
  email:
71
74
  - zhulik.gleb@gmail.com
72
75
  executables: []
@@ -85,6 +88,7 @@ files:
85
88
  - Gemfile.lock
86
89
  - LICENSE.txt
87
90
  - README.md
91
+ - Rakefile
88
92
  - bin/console
89
93
  - bin/setup
90
94
  - docker-compose.yml
@@ -97,22 +101,25 @@ files:
97
101
  - lib/grumlin/bytecode.rb
98
102
  - lib/grumlin/client.rb
99
103
  - lib/grumlin/edge.rb
100
- - lib/grumlin/order.rb
101
- - lib/grumlin/p.rb
102
104
  - lib/grumlin/path.rb
103
- - lib/grumlin/pop.rb
104
105
  - lib/grumlin/request_dispatcher.rb
105
106
  - lib/grumlin/step.rb
106
107
  - lib/grumlin/sugar.rb
107
- - lib/grumlin/t.rb
108
108
  - lib/grumlin/test/rspec.rb
109
109
  - lib/grumlin/test/rspec/db_cleaner_context.rb
110
110
  - lib/grumlin/test/rspec/gremlin_context.rb
111
+ - lib/grumlin/tools/order.rb
112
+ - lib/grumlin/tools/p.rb
113
+ - lib/grumlin/tools/pop.rb
114
+ - lib/grumlin/tools/scope.rb
115
+ - lib/grumlin/tools/t.rb
116
+ - lib/grumlin/tools/tool.rb
117
+ - lib/grumlin/tools/u.rb
118
+ - lib/grumlin/tools/with_options.rb
111
119
  - lib/grumlin/transport.rb
112
120
  - lib/grumlin/traversal.rb
113
121
  - lib/grumlin/typed_value.rb
114
122
  - lib/grumlin/typing.rb
115
- - lib/grumlin/u.rb
116
123
  - lib/grumlin/version.rb
117
124
  - lib/grumlin/vertex.rb
118
125
  homepage: https://github.com/zhulik/grumlin
@@ -140,5 +147,5 @@ requirements: []
140
147
  rubygems_version: 3.2.22
141
148
  signing_key:
142
149
  specification_version: 4
143
- summary: Gremlin query language DSL for Ruby.
150
+ summary: Gremlin graph traversal language DSL and client for Ruby.
144
151
  test_files: []
data/lib/grumlin/order.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module Order
5
- # TODO: share the code?
6
- class << self
7
- %i[asc desc].each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
11
-
12
- instance_variable_set(name, TypedValue.new(type: "Order", value: step))
13
- end
14
- end
15
- end
16
- end
17
- end
data/lib/grumlin/p.rb DELETED
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module P
5
- module P
6
- class Predicate < TypedValue
7
- def initialize(name, args:, arg_type: nil)
8
- super(type: "P")
9
- @name = name
10
- @args = args
11
- @arg_type = arg_type
12
- end
13
-
14
- def value
15
- @value ||=
16
- {
17
- predicate: @name,
18
- value: TypedValue.new(type: @arg_type, value: @args).to_bytecode
19
- }
20
- end
21
- end
22
-
23
- # TODO: support more predicates
24
- %w[eq neq].each do |predicate|
25
- define_method predicate do |*args|
26
- Predicate.new(predicate, args: args[0])
27
- end
28
- end
29
-
30
- %w[within without].each do |predicate|
31
- define_method predicate do |*args|
32
- args = if args.count == 1 && args[0].is_a?(Array)
33
- args[0]
34
- elsif args.count == 1 && args[0].is_a?(Set)
35
- args[0].to_a
36
- else
37
- args.to_a
38
- end
39
- Predicate.new(predicate, args: args, arg_type: "List")
40
- end
41
- end
42
- end
43
-
44
- extend P
45
- end
46
- end
data/lib/grumlin/pop.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module Pop
5
- # TODO: share the code?
6
- class << self
7
- %i[first last all mixed].each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
11
-
12
- instance_variable_set(name, TypedValue.new(type: "Pop", value: step))
13
- end
14
- end
15
- end
16
- end
17
- end
data/lib/grumlin/t.rb DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module T
5
- # TODO: share the code?
6
- class << self
7
- %i[id label].each do |step|
8
- define_method step do
9
- name = "@#{step}"
10
- return instance_variable_get(name) if instance_variable_defined?(name)
11
-
12
- instance_variable_set(name, TypedValue.new(type: "T", value: step))
13
- end
14
- end
15
- end
16
- end
17
- end
data/lib/grumlin/u.rb DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grumlin
4
- module U
5
- # TODO: add other start steps
6
- SUPPORTED_START_STEPS = %w[V addV count fold has out repeat unfold values].freeze
7
-
8
- class << self
9
- SUPPORTED_START_STEPS.each do |step|
10
- define_method step do |*args|
11
- AnonymousStep.new(step, *args)
12
- end
13
- end
14
- end
15
- end
16
- end