ceres 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b38b7e2d8628453da7be0e2aae9a4340ec930fd90b753a5c2abf943e73baa8d3
4
+ data.tar.gz: 934797928e8f06b68e0f244708ae5ad920273ac5cbcf45f81a5e56c8ec3cb727
5
+ SHA512:
6
+ metadata.gz: 4a4051ef093dda714bcb676dda3ff6408a2e998aa24c720a4b58721e72bbc52dd6a215ac43fd4bd0cdca7f22bf44876cfe715042f480ce972a9828acbf990460
7
+ data.tar.gz: a406a97bda949cb9e44e851125f71aa9ad9b728a08809afd6093be836c4b85ff107bf8a20ca30ff008885d838d2940fbcde7c54281a9c2c2b09f57447111b419
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /spec/examples.txt
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,80 @@
1
+ AllCops:
2
+ DisplayCopNames: true
3
+ TargetRubyVersion: 2.2
4
+
5
+ Lint/AssignmentInCondition:
6
+ AllowSafeAssignment: false
7
+
8
+ Lint/BlockAlignment:
9
+ AlignWith: start_of_line
10
+
11
+ Lint/EndAlignment:
12
+ AlignWith: variable
13
+
14
+ Metrics/LineLength:
15
+ Max: 100
16
+
17
+ Metrics/MethodLength:
18
+ Max: 20
19
+
20
+ Metrics/ParameterLists:
21
+ Max: 10
22
+
23
+ Style/CaseIndentation:
24
+ IndentWhenRelativeTo: end
25
+
26
+ Metrics/ClassLength:
27
+ Max: 1500
28
+
29
+ Style/CollectionMethods:
30
+ Enabled: true
31
+
32
+ # TODO: This should be enabled
33
+ Style/Documentation:
34
+ Enabled: false
35
+
36
+ Style/ElseAlignment:
37
+ Enabled: false
38
+
39
+ Style/FormatString:
40
+ EnforcedStyle: percent
41
+
42
+ Style/FrozenStringLiteralComment:
43
+ EnforcedStyle: always
44
+
45
+ # I like this in theory, but sometimes it weirds out
46
+ Style/GuardClause:
47
+ Enabled: false
48
+
49
+ Style/HashSyntax:
50
+ EnforcedStyle: ruby19_no_mixed_keys
51
+
52
+ Style/MultilineOperationIndentation:
53
+ Enabled: false
54
+
55
+ Style/ParenthesesAroundCondition:
56
+ AllowSafeAssignment: false
57
+
58
+ Style/RaiseArgs:
59
+ Enabled: false
60
+
61
+ Style/RedundantReturn:
62
+ Enabled: false
63
+
64
+ Style/RedundantSelf:
65
+ Enabled: false
66
+
67
+ Style/StringLiterals:
68
+ EnforcedStyle: double_quotes
69
+
70
+ Style/SignalException:
71
+ EnforcedStyle: only_raise
72
+
73
+ Style/SpaceAroundEqualsInParameterDefault:
74
+ EnforcedStyle: space
75
+
76
+ Style/SpaceInsideRangeLiteral:
77
+ Enabled: false
78
+
79
+ Style/SymbolArray:
80
+ Enabled: true
data/.travis.yml ADDED
@@ -0,0 +1,18 @@
1
+ sudo: false
2
+ language: ruby
3
+ cache: bundler
4
+
5
+ before_install: gem install bundler -v 1.13.1
6
+ bundler_args: --jobs=3 --retry=3
7
+
8
+ rvm:
9
+ - 2.2.5
10
+ - 2.3.1
11
+ - ruby-head
12
+ - jruby-head
13
+
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: ruby-head
17
+
18
+ fast_finish: true
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
6
+
7
+ group :test do
8
+ gem "rake"
9
+ gem "rspec"
10
+ gem "rubocop"
11
+ gem "simplecov"
12
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2016 Ceres contributors
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # Ceres #
2
+
3
+ [![Build Status](https://travis-ci.org/aventine-softworks/ceres.svg?branch=master)](https://travis-ci.org/aventine-softworks/ceres)
4
+
5
+ Ceres is a gem that extends the Ruby standard library with some cool new features, but it doesn't monkey patch anything or break anything you already have, so just require what you want or go all in with `require 'ceres'`. The main features are mostly immutable type safe classes, synchronized objects, notification centers, and thread pools.
6
+
7
+ The main goal is to allow sloppy people like me write good code by catching errors instead of just silently letting them slip.
8
+
9
+
10
+ ## Installation ##
11
+
12
+ If you're using bundler you can just add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'ceres'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle install
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install ceres
25
+
26
+
27
+ ## Development ##
28
+
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.
30
+
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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+
34
+ ## License ##
35
+
36
+ Ceres is released under the MIT license:
37
+
38
+ www.opensource.org/licenses/MIT
39
+
40
+
41
+ ## Contributing ##
42
+
43
+ Bug reports (and pull requests) are appreciated on GitHub at https://github.com/rawrasaur/ceres, I'm sorry if I'm slow at responding.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
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
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "safe_structure"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
data/ceres.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ lib = File.expand_path("../lib", __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+
7
+ require "ceres/version"
8
+
9
+ Gem::Specification.new do |spec|
10
+ spec.name = "ceres"
11
+ spec.version = Ceres::VERSION
12
+ spec.authors = ["Aurora"]
13
+ spec.email = ["aurora@aventine.se"]
14
+
15
+ spec.summary = " A collection of useful things"
16
+ spec.homepage = "https://github.com/rawrasaur/ceres"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,74 @@
1
+ require "ceres/reader"
2
+ require "ceres/writer"
3
+ require "ceres/inspector"
4
+
5
+ module Ceres
6
+ class Attribute
7
+ attr_reader :name
8
+
9
+ attr_accessor :description
10
+ attr_accessor :variable
11
+ attr_accessor :target
12
+ attr_accessor :reader
13
+ attr_accessor :writer
14
+ attr_accessor :inspector
15
+
16
+ class DSL
17
+ def initialize(object, &block)
18
+ @object = object
19
+
20
+ self.instance_exec(&block) if block
21
+ end
22
+
23
+ def description(text)
24
+ @object.description = text
25
+ end
26
+
27
+ def target(symbol)
28
+ @object.target = symbol
29
+ end
30
+
31
+ def variable(symbol)
32
+ @object.variable = symbol
33
+ end
34
+
35
+ def reader(disabled: false, **args, &block)
36
+ reader = Ceres::Reader.new(@object, **args, &block) unless disabled
37
+
38
+ @object.reader = reader
39
+ end
40
+
41
+ def writer(disabled: false, &block)
42
+ writer = Ceres::Writer.new(@object, &block) unless disabled
43
+
44
+ @object.writer = writer
45
+ end
46
+
47
+ def inspector(disabled: false, &block)
48
+ inspector = Ceres::Inspector.new(&block) unless disabled
49
+
50
+ @object.inspector = inspector
51
+ end
52
+ end
53
+
54
+ def initialize(name, &block)
55
+ @name = name.to_sym
56
+
57
+ @description = nil
58
+ @variable = "@#{name}".to_sym
59
+
60
+ @reader = Ceres::Reader.new(self)
61
+ @writer = nil
62
+ @inspector = Ceres::Inspector.new
63
+
64
+ Ceres::Attribute::DSL.new(self, &block)
65
+ end
66
+
67
+ def apply(klass)
68
+ @reader.apply(klass) if @reader
69
+ @writer.apply(klass) if @writer
70
+
71
+ klass
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,17 @@
1
+ module Ceres
2
+ class Inspector
3
+ def initialize(&block)
4
+ @block = block
5
+ end
6
+
7
+ def inspect_object(object)
8
+ if @block
9
+ @block.call(object)
10
+ else
11
+ object
12
+ end.inspect
13
+ rescue => e
14
+ "<EXCEPTION RAISED IN INSPECT: #{e.inspect}>"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,44 @@
1
+ require "ceres/attribute"
2
+
3
+ module Ceres
4
+ class Object
5
+ def self.inherited(klass)
6
+ klass.instance_exec { @attributes = [] }
7
+ end
8
+
9
+ def self.attribute(name, &block)
10
+ attribute = Ceres::Attribute.new(name, &block)
11
+ attribute.apply(self)
12
+
13
+ @attributes << attribute
14
+ end
15
+
16
+ def self.attributes(all: true)
17
+ if all
18
+ self.ancestors.flat_map do |ancestor|
19
+ if ancestor.respond_to?(:attributes)
20
+ ancestor.attributes(all: false)
21
+ else
22
+ []
23
+ end
24
+ end
25
+ elsif defined?(@attributes)
26
+ @attributes
27
+ else
28
+ []
29
+ end
30
+ end
31
+
32
+ def inspect
33
+ attributes = self.class.attributes.map do |attribute|
34
+ if attribute.inspector
35
+ name = attribute.name
36
+
37
+ " #{name}: #{attribute.inspector.inspect_object(self.send(name))}"
38
+ end
39
+ end.compact.join(",")
40
+
41
+ sprintf("#<%p:%0#18x%s>", self.class, self.object_id << 1, attributes)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,77 @@
1
+ module Ceres
2
+ class Reader
3
+ attr_reader :attribute
4
+ attr_reader :block
5
+
6
+ def initialize(attribute, cache: false, &block)
7
+ @attribute = attribute
8
+ @cache = cache
9
+ @block = block
10
+ end
11
+
12
+ def cache?
13
+ @cache
14
+ end
15
+
16
+ def name
17
+ @attribute.name
18
+ end
19
+
20
+ def target
21
+ @attribute.target
22
+ end
23
+
24
+ def variable
25
+ @attribute.variable
26
+ end
27
+
28
+ def to_proc
29
+ self.cache? ? to_cached_proc : to_uncached_proc
30
+ end
31
+
32
+ def apply(klass)
33
+ name = self.name
34
+
35
+ if allow_reader_optimisation?
36
+ klass.instance_exec { attr_reader name }
37
+ else
38
+ reader = self.to_proc
39
+
40
+ klass.instance_exec { define_method(name, &reader) }
41
+ end
42
+ end
43
+
44
+ private def allow_reader_optimisation?
45
+ !@block && self.target.nil? && self.variable == "@#{self.name}".to_sym
46
+ end
47
+
48
+ private def to_uncached_proc
49
+ target = self.target
50
+ variable = self.variable
51
+ block = self.block
52
+
53
+ if target
54
+ if block
55
+ proc { instance_variable_get(target).instance_exec(&block) }
56
+ else
57
+ proc { instance_variable_get(target).instance_variable_get(variable) }
58
+ end
59
+ else
60
+ block || proc { instance_variable_get(variable) }
61
+ end
62
+ end
63
+
64
+ private def to_cached_proc
65
+ uncached_proc = to_uncached_proc
66
+ variable = self.variable
67
+
68
+ proc do
69
+ if instance_variable_defined?(variable)
70
+ instance_variable_get(variable)
71
+ else
72
+ instance_variable_set(variable, instance_exec(&uncached_proc))
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ceres
4
+ VERSION = "0.2.0".freeze
5
+ end
@@ -0,0 +1,63 @@
1
+ module Ceres
2
+ class Writer
3
+ attr_reader :attribute
4
+ attr_reader :block
5
+
6
+ def initialize(attribute, &block)
7
+ @attribute = attribute
8
+ @block = block
9
+ end
10
+
11
+ def name
12
+ @attribute.name
13
+ end
14
+
15
+ def target
16
+ @attribute.target
17
+ end
18
+
19
+ def variable
20
+ @attribute.variable
21
+ end
22
+
23
+ def to_proc
24
+ target = self.target
25
+ variable = self.variable
26
+ block = self.block
27
+
28
+ if target
29
+ if block
30
+ proc do |v|
31
+ t = instance_variable_get(target)
32
+ t.instance_variable_set(variable, t.instance_exec(v, &block))
33
+ end
34
+ else
35
+ proc { |v| instance_variable_get(target).instance_variable_set(variable, v) }
36
+ end
37
+ else
38
+ if block
39
+ proc { |v| instance_variable_set(variable, instance_exec(v, &block)) }
40
+ else
41
+ proc { |v| instance_variable_set(variable, v) }
42
+ end
43
+ end
44
+ end
45
+
46
+ def apply(klass)
47
+ if allow_writer_optimisation?
48
+ name = self.name
49
+
50
+ klass.instance_exec { attr_writer name }
51
+ else
52
+ name = "#{@attribute.name}=".to_sym
53
+ writer = self.to_proc
54
+
55
+ klass.instance_exec { define_method(name, &writer) }
56
+ end
57
+ end
58
+
59
+ private def allow_writer_optimisation?
60
+ !@block && self.target.nil? && self.variable == "@#{@attribute.name}".to_sym
61
+ end
62
+ end
63
+ end
data/lib/ceres.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ceres/version"
4
+
5
+ require "ceres/attribute"
6
+ require "ceres/object"
7
+ require "ceres/reader"
8
+ require "ceres/writer"
9
+
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ceres
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Aurora
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-06-20 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - aurora@aventine.se
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - ".rspec"
22
+ - ".rubocop.yml"
23
+ - ".travis.yml"
24
+ - Gemfile
25
+ - LICENSE
26
+ - README.md
27
+ - Rakefile
28
+ - bin/console
29
+ - bin/setup
30
+ - ceres.gemspec
31
+ - lib/ceres.rb
32
+ - lib/ceres/attribute.rb
33
+ - lib/ceres/inspector.rb
34
+ - lib/ceres/object.rb
35
+ - lib/ceres/reader.rb
36
+ - lib/ceres/version.rb
37
+ - lib/ceres/writer.rb
38
+ homepage: https://github.com/rawrasaur/ceres
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.7.6
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: A collection of useful things
62
+ test_files: []