safe_values 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ba03abf1ce02d1e319edf07d93dfdd9c95c7985a03085a964b75159672483143
4
+ data.tar.gz: 1aa9bb295da60cca721fdbb3c8826399845159c4ea5ef7364e3c1cd999494b20
5
+ SHA512:
6
+ metadata.gz: 5848e9df32a06a5a611f8bdc6cc47f1ffec2edcd989c10a834fbaa57588b0a42d73df9f327fd8776fe4c8e2772b8e785f32653ebc713d861ed4d8c84ff044017
7
+ data.tar.gz: 7b830c4a56c889e7c64cfeb7bfabfcdc3a90b6b53c27fb99d621ef3cf7e4e1accd745ecaf2e26a19031a19d98b171aa4873797f6eada6c384b2a96cfcb76aef2
@@ -0,0 +1,94 @@
1
+ version: 2.1
2
+
3
+ executors:
4
+ ruby:
5
+ parameters:
6
+ ruby-version:
7
+ type: string
8
+ default: "2.6"
9
+ gemfile:
10
+ type: string
11
+ default: "Gemfile"
12
+ docker:
13
+ - image: circleci/ruby:<< parameters.ruby-version >>
14
+ environment:
15
+ BUNDLE_JOBS: 3
16
+ BUNDLE_RETRY: 3
17
+ BUNDLE_PATH: vendor/bundle
18
+ RAILS_ENV: test
19
+ BUNDLE_GEMFILE: << parameters.gemfile >>
20
+
21
+ jobs:
22
+ test:
23
+ parameters:
24
+ ruby-version:
25
+ type: string
26
+ executor:
27
+ name: ruby
28
+ ruby-version: << parameters.ruby-version >>
29
+ parallelism: 1
30
+ steps:
31
+ - checkout
32
+
33
+ - run:
34
+ # Remove the non-appraisal gemfile for safety: we never want to use it.
35
+ name: Prepare bundler
36
+ command: bundle -v
37
+
38
+ - run:
39
+ name: Compute a gemfile lock
40
+ command: bundle lock && cp "${BUNDLE_GEMFILE}.lock" /tmp/gem-lock
41
+
42
+ - restore_cache:
43
+ keys:
44
+ - safe_values-<< parameters.ruby-version >>-{{ checksum "/tmp/gem-lock" }}
45
+ - safe_values-
46
+
47
+ - run:
48
+ name: Bundle Install
49
+ command: bundle check || bundle install
50
+
51
+ - save_cache:
52
+ key: safe_values-<< parameters.ruby-version >>-{{ checksum "/tmp/gem-lock" }}
53
+ paths:
54
+ - vendor/bundle
55
+
56
+ - run:
57
+ name: Run rspec
58
+ command: bundle exec rspec --profile 10 --format RspecJunitFormatter --out test_results/rspec.xml --format progress
59
+
60
+ - store_test_results:
61
+ path: test_results
62
+
63
+ publish:
64
+ executor: ruby
65
+ steps:
66
+ - checkout
67
+ - run:
68
+ name: Setup Rubygems
69
+ command: |
70
+ mkdir ~/.gem &&
71
+ echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials &&
72
+ chmod 0600 ~/.gem/credentials
73
+ - run:
74
+ name: Publish to Rubygems
75
+ command: |
76
+ gem build safe_values.gemspec
77
+ gem push safe_values-*.gem
78
+
79
+ workflows:
80
+ version: 2.1
81
+ build:
82
+ jobs:
83
+ - test:
84
+ name: 'ruby 2.5'
85
+ ruby-version: "2.5"
86
+ - test:
87
+ name: 'ruby 2.6'
88
+ ruby-version: "2.6"
89
+ - publish:
90
+ filters:
91
+ branches:
92
+ only: master
93
+ tags:
94
+ ignore: /.*/
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
10
+
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ dist: trusty
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5
7
+ - 2.6
8
+ before_install:
9
+ # Travis' Ruby 2.5.0 ships broken rubygems, won't run rake.
10
+ # Workaround: update rubygems. See travis-ci issue 8978
11
+ - gem install bundler
12
+ notifications:
13
+ email: false
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in safe_values.gemspec
6
+ gemspec
7
+
8
+ gem 'rspec_junit_formatter'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017 DMM.com
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # SafeValues
2
+ [![Build Status](https://travis-ci.org/iknow/safe_values.svg?branch=master)](https://travis-ci.org/iknow/safe_values)
3
+
4
+ `Value` generates `Struct` classes with safer constructors. It is designed to
5
+ provide a superset of the interface of the `Values` gem, with better
6
+ performance, by subclassing actual native `Struct`s.
7
+
8
+ `Value` constructors require all mandatory arguments to be provided, and supply
9
+ default values for all optional arguments. Additionally, the resulting instance
10
+ is frozen. To obtain a mutable `Value`, use `dup`.
11
+
12
+ `Value` types are created similarly to `Struct`s, with the addition that
13
+ optional arguments are may be specified as keyword arguments:
14
+
15
+ ```ValueType = Value.new(:a, :b, c: default_value)```
16
+
17
+ The default values to optional arguments are saved at class creation time and
18
+ supplied as default constructor arguments to instances. Default values are
19
+ aliased, so providing mutable defaults is discouraged.
20
+
21
+ Two instance constructors are provided, with positional and keyword arguments.
22
+
23
+ Value types may be constructed with positional arguments using `new`. Arguments
24
+ are provided in the same order as specified at class initialization time, with
25
+ mandatory arguments before optional ones. For example:
26
+
27
+ ```ValueType.new(1, 2)```
28
+ or
29
+ ```ValueType.new(1, 2, 3)```
30
+
31
+ Value types may be constructed with keyword arguments using `with`. For example:
32
+
33
+ ```ValueType.with(a: 1, b: 2)```
34
+ or
35
+ ```ValueType.with(a: 1, b: 2, c: 3)```
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "safe_values"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ require "safe_values/version"
2
+ require "value"
3
+
4
+ module SafeValues
5
+ end
@@ -0,0 +1,3 @@
1
+ module SafeValues
2
+ VERSION = "1.0.1"
3
+ end
data/lib/value.rb ADDED
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ # `Value` generates `Struct` classes with safer constructors. It is designed to
4
+ # provide a superset of the interface of the `Values` gem, with better
5
+ # performance, by subclassing actual native Structs.
6
+ #
7
+ # `Value` constructors require all mandatory arguments to be provided, and
8
+ # supply default values for all optional arguments. Additionally, the resulting
9
+ # instance is frozen. To obtain a mutable Value, `dup` the result.
10
+ #
11
+ # `Value` structure classes are created similarly to `Struct`s, with the
12
+ # addition that optional arguments are may be specified as keyword arguments:
13
+ # `ValueType = Value.new(:a, :b, c: default_value)`. The default values to
14
+ # optional arguments are saved at class creation time and supplied as default
15
+ # constructor arguments to instances. Default values are aliased, so providing
16
+ # mutable defaults is discouraged.
17
+ #
18
+ # Two instance constructors are provided, with positional and keyword arguments.
19
+ #
20
+ # Value types may be constructed with positional arguments using `new`.
21
+ # Arguments are provided in the same order as specified at class initialization
22
+ # time, with mandatory arguments before optional ones.
23
+ # For example: `ValueType.new(1, 2)`, `ValueType.new(1, 2, 3)`
24
+ #
25
+ # Value types may be constructed with keyword arguments using `with`.
26
+ # For example: `ValueType.with(a: 1, b: 2, c: 3)`
27
+ class Value < Struct
28
+ class << self
29
+ def new(*required_args, **optional_args, &block)
30
+ arguments = {}
31
+ required_args.each { |arg| arguments[arg] = true }
32
+ optional_args.each_key { |arg| arguments[arg] = false }
33
+ validate_names(*arguments.keys)
34
+
35
+ clazz = super(*arguments.keys, &nil)
36
+
37
+ # define class and instance methods in modules so that the class can
38
+ # override them
39
+ keyword_constructor = generate_keyword_constructor(arguments)
40
+ class_method_module = Module.new do
41
+ module_eval(keyword_constructor)
42
+ define_method(:__constructor_default) do |name|
43
+ optional_args.fetch(name)
44
+ end
45
+ end
46
+ clazz.extend(class_method_module)
47
+
48
+ constructor = generate_constructor(arguments)
49
+ instance_method_module = Module.new do
50
+ module_eval(constructor)
51
+ end
52
+ clazz.include(instance_method_module)
53
+
54
+ # Evaluate the block in the context of the class
55
+ clazz.class_eval(&block) if block_given?
56
+
57
+ clazz
58
+ end
59
+
60
+ private
61
+
62
+ def validate_names(*params)
63
+ params.each do |param|
64
+ unless param.is_a?(Symbol) && param =~ /\A[a-z_][a-zA-Z_0-9]*\z/
65
+ raise ArgumentError.new("param #{param} is not a valid identifier")
66
+ end
67
+ end
68
+ end
69
+
70
+ # Generates an initialize method with required and optional parameters,
71
+ # delegating to the Struct constructor. Parameter names must have already
72
+ # been validated.
73
+ #
74
+ # For a Value.new(:a, b: x), will define the method:
75
+ #
76
+ # def initialize(a, b = self.class.__constructor_default(:b))
77
+ # super(a, b)
78
+ # freeze
79
+ # end
80
+ def generate_constructor(arguments)
81
+ params = arguments.map do |arg_name, required|
82
+ if required
83
+ arg_name
84
+ else
85
+ "#{arg_name} = self.class.__constructor_default(:#{arg_name})"
86
+ end
87
+ end
88
+
89
+ <<-SRC
90
+ def initialize(#{params.join(", ")})
91
+ super(#{arguments.keys.join(", ")})
92
+ freeze
93
+ end
94
+ SRC
95
+ end
96
+
97
+ # Generates an alternative construction method accepting keyword arguments
98
+ # for required and optional parameters, delegating to the generated
99
+ # constructor. Parameter names must have already been validated.
100
+ #
101
+ # For a Value.new(:a, b: x), will define the (class) method:
102
+ #
103
+ # def with(a:, b: __constructor_default(:b))
104
+ # self.new(a, b)
105
+ # end
106
+ def generate_keyword_constructor(arguments)
107
+ params = arguments.map do |arg_name, required|
108
+ if required
109
+ "#{arg_name}:"
110
+ else
111
+ "#{arg_name}: __constructor_default(:#{arg_name})"
112
+ end
113
+ end
114
+
115
+ <<-SRC
116
+ def with(#{params.join(", ")})
117
+ self.new(#{arguments.keys.join(", ")})
118
+ end
119
+ SRC
120
+ end
121
+ end
122
+
123
+ def with(hash = {})
124
+ return self if hash.empty?
125
+ self.class.with(to_h.merge(hash))
126
+ end
127
+ end
@@ -0,0 +1,26 @@
1
+
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'safe_values/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'safe_values'
8
+ spec.version = SafeValues::VERSION
9
+ spec.authors = ['DMM Eikaiwa']
10
+ spec.email = ['dev@iknow.jp']
11
+
12
+ spec.summary = %q{Struct classes with safer constructors.}
13
+ spec.homepage = 'http://github.com/iknow/safe_values'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_development_dependency 'bundler'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec'
26
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safe_values
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - DMM Eikaiwa
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-04-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - dev@iknow.jp
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".circleci/config.yml"
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - lib/safe_values.rb
73
+ - lib/safe_values/version.rb
74
+ - lib/value.rb
75
+ - safe_values.gemspec
76
+ homepage: http://github.com/iknow/safe_values
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubygems_version: 3.0.3
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Struct classes with safer constructors.
99
+ test_files: []