rubysierung 0.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 +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +87 -0
- data/Rakefile +10 -0
- data/lib/rubysierung/types.rb +4 -0
- data/lib/rubysierung/version.rb +3 -0
- data/lib/rubysierung.rb +96 -0
- data/rubysierung.gemspec +24 -0
- data/test/test_rubysierung.rb +100 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 875fa267b870b098ff0ed94d788a09f105aad733
|
4
|
+
data.tar.gz: 9845df8afc589de503809d09963258c6560aa5a6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 04528c6d13c3314c3b732f08219accd7429258fda266b8d4e755971a49668e741ed570c787ec0e58bd526b5342e70e5292ed261b00de57608cab8683a17111f3
|
7
|
+
data.tar.gz: 86922f0ee69b148d298b1781fb4e048009de92b762ce698ba0fd0e686afe61ac9f3f09ea50db680c6a91d133952427cc003c5499fe1825531319db096644129f
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 doodzik
|
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,87 @@
|
|
1
|
+
# Rubysierung
|
2
|
+
|
3
|
+
[](https://travis-ci.org/doodzik/rubysierung)
|
4
|
+
|
5
|
+
Rubysierung is the type system Ruby deserves
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# ruby 2.1.0
|
13
|
+
|
14
|
+
gem 'rubysierung'
|
15
|
+
gem 'CallBaecker', '~> 0.0.3'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install rubysierung
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'CallBaecker'
|
30
|
+
require 'rubysierung'
|
31
|
+
|
32
|
+
# define a custom type
|
33
|
+
class CustomType
|
34
|
+
end
|
35
|
+
|
36
|
+
class Example
|
37
|
+
extend Rubysierung
|
38
|
+
include CallBaecker # include Callbaecker after Rubysierung
|
39
|
+
|
40
|
+
# if the type doesnt match Rubisierung will raise an Error messages
|
41
|
+
|
42
|
+
# add custom Types
|
43
|
+
# [TypeClass, StandartDuckTypeAsSymbol, StrictDuckTypeAsSymbol]# TODO change to proper name
|
44
|
+
@__type_add.call([CustomTyp, :to_s, :to_int])
|
45
|
+
|
46
|
+
# define foo to respond to :to_s and bar to :to_i
|
47
|
+
def one(foo: String, bar: Integer)
|
48
|
+
[foo, bar]
|
49
|
+
end
|
50
|
+
|
51
|
+
# you can still define empty/default parameters
|
52
|
+
def self.three(foo: , bar: 'hallo World')
|
53
|
+
[foo, bar]
|
54
|
+
end
|
55
|
+
|
56
|
+
# use a custom type
|
57
|
+
def self.four(foo: ,bar: CustomType)
|
58
|
+
[foo, bar]
|
59
|
+
end
|
60
|
+
|
61
|
+
# define foo to respond to :to_str (strict type)
|
62
|
+
def self.five(foo: Strict::String, bar: Integer)
|
63
|
+
[foo, bar]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
## what would it look like normally
|
69
|
+
```ruby
|
70
|
+
def one(foo:, bar:)
|
71
|
+
sFoo = foo.to_s
|
72
|
+
iBar = bar.to_i
|
73
|
+
[sFoo, iBar]
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
## Roadmap
|
78
|
+
* add all Standard Types
|
79
|
+
* add feature to add a default argument for a specified Type
|
80
|
+
|
81
|
+
## Contributing
|
82
|
+
|
83
|
+
1. Fork it ( https://github.com/doodzik/rubysierung/fork )
|
84
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
85
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
86
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
87
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/lib/rubysierung.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require "rubysierung/version"
|
2
|
+
require 'rubysierung/types'
|
3
|
+
|
4
|
+
|
5
|
+
module Rubysierung
|
6
|
+
module Error
|
7
|
+
class Standard < StandardError; end
|
8
|
+
class Strict < StandardError; end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.extended(base)
|
12
|
+
base.instance_variable_set :@__types_show, -> () do
|
13
|
+
puts @__types
|
14
|
+
end
|
15
|
+
|
16
|
+
base.instance_variable_set :@__type_add, -> (type) do
|
17
|
+
@__types << type
|
18
|
+
end
|
19
|
+
|
20
|
+
base.instance_variable_set :@__before_hook, -> (i,ii, callee) do
|
21
|
+
@__error_data[:caller] = callee
|
22
|
+
Rubysierung.convert_multiple(klass_hash: i, value_hash: ii)
|
23
|
+
end
|
24
|
+
|
25
|
+
base.instance_variable_set :@__setup_instance_method, -> (_self, name) do
|
26
|
+
file, line = _self.instance_method(name.to_sym).source_location
|
27
|
+
@__error_data[:method_object] = _self.name
|
28
|
+
@__error_data[:method_file] = file
|
29
|
+
@__error_data[:method_name] = name
|
30
|
+
@__error_data[:method_line] = line -1
|
31
|
+
get_default_hash_from_fileline(file: file, line: line-1)
|
32
|
+
end
|
33
|
+
|
34
|
+
base.instance_variable_set :@__setup_class_method, -> (_self, name) do
|
35
|
+
file, line = _self.method(name.to_sym).source_location
|
36
|
+
@__error_data[:method_object] = _self.name
|
37
|
+
@__error_data[:method_file] = file
|
38
|
+
@__error_data[:method_name] = name
|
39
|
+
@__error_data[:method_line] = line -1
|
40
|
+
get_default_hash_from_fileline(file: file, line: line-1)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
@__types = [[String, :to_s, :to_str], [Integer, :to_i, :to_int]]
|
45
|
+
@__error_data = {}
|
46
|
+
class << self
|
47
|
+
def get_default_hash_from_fileline(file:, line:)
|
48
|
+
params_matcher = /([a-z][a-zA-Z]+):\s*([^,\n)]+)/
|
49
|
+
def_line = IO.readlines(file)[line]
|
50
|
+
flatten_hash = Hash[*def_line.scan(params_matcher).flatten]
|
51
|
+
myhash = flatten_hash.reject { |k,v| v =~ /^[^A-Z]/}
|
52
|
+
Hash[myhash.map{|(k,v)| [k.to_sym, Kernel.const_get(v)]}]
|
53
|
+
end
|
54
|
+
|
55
|
+
def convert_multiple(klass_hash:, value_hash:)
|
56
|
+
return_hash = {}
|
57
|
+
return value_hash if klass_hash.empty?
|
58
|
+
klass_hash.keys.map do |key|
|
59
|
+
@__error_data[:var_sym] = key
|
60
|
+
return_hash[key] = convert(klass: klass_hash[key], value: value_hash[key])
|
61
|
+
end
|
62
|
+
value_hash.merge return_hash
|
63
|
+
end
|
64
|
+
|
65
|
+
def convert(klass:, value:)
|
66
|
+
strict = 0
|
67
|
+
@__types.map do |type|
|
68
|
+
strict ,klass = get_kind(klass: klass)
|
69
|
+
begin
|
70
|
+
if klass == type[0]
|
71
|
+
return value.send(type[1+strict])
|
72
|
+
end
|
73
|
+
rescue NoMethodError
|
74
|
+
if strict == 0
|
75
|
+
raise Rubysierung::Error::Standart, "Rubysierung::Error::Standart: Class:#{klass}, DuckType:#{type[2]}, Method:#{@__error_data[:method_object]}:#{@__error_data[:method_file]}#{@__error_data[:method_name]}:#{@__error_data[:method_line]} -- called on #{@__error_data[:caller]} with #{@__error_data[:var_sym]}:#{value} of #{value.class} doesn't respond to #{type[2]}"
|
76
|
+
|
77
|
+
else
|
78
|
+
# return argument, param, duck_type, calle/receiver -> file, line
|
79
|
+
raise Rubysierung::Error::Strict, "Rubysierung::Error::Strict: Class:#{klass}, DuckType:#{type[2]}, Method:#{@__error_data[:method_object]}:#{@__error_data[:method_file]}#{@__error_data[:method_name]}:#{@__error_data[:method_line]} -- called on #{@__error_data[:caller]} with #{@__error_data[:var_sym]}:#{value} of #{value.class} doesn't respond to #{type[2]}"
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
value
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_kind(klass:)
|
88
|
+
if klass.respond_to? :name
|
89
|
+
splitted = klass.name.split('::')
|
90
|
+
splitted[0] == 'Strict' ? [1, Kernel.const_get(splitted[1])] : [0, klass]
|
91
|
+
else
|
92
|
+
[0, klass]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/rubysierung.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rubysierung/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rubysierung"
|
8
|
+
spec.version = Rubysierung::VERSION
|
9
|
+
spec.authors = ["doodzik"]
|
10
|
+
spec.email = ["4004blog@gmail.com"]
|
11
|
+
spec.summary = %q{Rubysierung is the type system Ruby deserves}
|
12
|
+
spec.homepage = "https://github.com/doodzik/rubysierung"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
spec.add_development_dependency "CallBaecker", "> 0.0.3"
|
23
|
+
spec.add_development_dependency "minitest"
|
24
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'CallBaecker'
|
3
|
+
require 'rubysierung'
|
4
|
+
|
5
|
+
class CustomTyp
|
6
|
+
end
|
7
|
+
|
8
|
+
class Setup
|
9
|
+
extend Rubysierung
|
10
|
+
include CallBaecker
|
11
|
+
|
12
|
+
@__type_add.call([CustomTyp, :to_s, :to_str])
|
13
|
+
|
14
|
+
def example1(foo: String, bar: Integer)
|
15
|
+
[foo, bar]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.example2(foo: String, bar: Integer)
|
19
|
+
[foo, bar]
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.example3(foo: , bar: 'hallo World')
|
23
|
+
[foo, bar]
|
24
|
+
end
|
25
|
+
|
26
|
+
# custom Class
|
27
|
+
def self.example4(foo: ,bar: CustomTyp)
|
28
|
+
[foo, bar]
|
29
|
+
end
|
30
|
+
|
31
|
+
# strict
|
32
|
+
def self.example5(foo: Strict::String, bar: Integer)
|
33
|
+
[foo, bar]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class RubysierungTest < Minitest::Test
|
38
|
+
def test_rubisierung_converte_Int_to_string
|
39
|
+
assert_equal('23', Rubysierung.convert(klass: String, value: 23))
|
40
|
+
end
|
41
|
+
def test_rubisierung_converte_string_to_Int
|
42
|
+
assert_equal(23, Rubysierung.convert(klass: Integer, value: '23'))
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_rubisierung_converte_pass_nonexisting_klass_then_return_value
|
46
|
+
assert_equal('23', Rubysierung.convert(klass: 'huhu', value: '23'))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_run_type_hash_agains_value_hash
|
50
|
+
assert_equal({foo: 23, bar:'23'},
|
51
|
+
Rubysierung.convert_multiple(value_hash: {foo: '23', bar: 23},
|
52
|
+
klass_hash: {foo: Integer, bar: String}))
|
53
|
+
end
|
54
|
+
def test_run_type_hash_agains_value_hash_without_a_class_on_klass_hash
|
55
|
+
assert_equal({foo: '23', bar:'23'},
|
56
|
+
Rubysierung.convert_multiple(value_hash: {foo: '23', bar: 23},
|
57
|
+
klass_hash: {foo: 14, bar: String}))
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_is_strict
|
61
|
+
assert_equal([0, String], Rubysierung.get_kind(klass: String))
|
62
|
+
assert_equal([1, String], Rubysierung.get_kind(klass: Strict::String))
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_example_2_standart
|
66
|
+
foo, bar= Setup.example2(foo: 4, bar: '3')
|
67
|
+
assert_equal(3, bar)
|
68
|
+
assert_equal('4', foo)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_example_1_instance_method
|
72
|
+
foo, bar= Setup.new.example1(foo: 4, bar: '3')
|
73
|
+
assert_equal(3, bar)
|
74
|
+
assert_equal('4', foo)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_example_3_default_works
|
78
|
+
foo, bar= Setup.example3(foo: 4)
|
79
|
+
assert_equal('hallo World', bar)
|
80
|
+
assert_equal(4, foo)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_example_4_custum_type
|
84
|
+
foo, bar = Setup.example4(foo: 4, bar: 3)
|
85
|
+
assert_equal('3', bar)
|
86
|
+
assert_equal(4, foo)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_example_5_strict_type
|
90
|
+
foo, bar = Setup.example5(foo: '4', bar: 2)
|
91
|
+
assert_equal(2, bar)
|
92
|
+
assert_equal('4', foo)
|
93
|
+
begin
|
94
|
+
Setup.example5(foo: 4, bar: 2)
|
95
|
+
assert_equal(false, true)
|
96
|
+
rescue StandardError => e
|
97
|
+
assert_equal(true, true)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubysierung
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- doodzik
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-04 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: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
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: CallBaecker
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.0.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.0.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- 4004blog@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/rubysierung.rb
|
83
|
+
- lib/rubysierung/types.rb
|
84
|
+
- lib/rubysierung/version.rb
|
85
|
+
- rubysierung.gemspec
|
86
|
+
- test/test_rubysierung.rb
|
87
|
+
homepage: https://github.com/doodzik/rubysierung
|
88
|
+
licenses:
|
89
|
+
- MIT
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.2.2
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: Rubysierung is the type system Ruby deserves
|
111
|
+
test_files:
|
112
|
+
- test/test_rubysierung.rb
|
113
|
+
has_rdoc:
|