define-poro 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 033b78f766bc6090768bb0ab44668594d5f1e6a4
4
+ data.tar.gz: a9790b5fbb89d3f539594d5c80b8ee199617bf47
5
+ SHA512:
6
+ metadata.gz: 8abf6b17bd0ce8384d46f373dd5af53737a7bec5691e2b4e32b6d0531fc41b18ca2e558d3f6dbfe0b7eae88b4bccffde092fc2f885a133909180b260b6724f66
7
+ data.tar.gz: f3774c785ce47070349f4aad8123403b72cf32d292166c9ca45991a382a03da7e0edb41ae07863310497bb8306a05b33e443288561e9295361ef622a64ab5de4
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Karolis Astrauka
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.
@@ -0,0 +1,103 @@
1
+ # Define Poro
2
+
3
+ Plain Old Ruby Object class builder from provided attribute list and block.
4
+
5
+ ## Rationale
6
+
7
+ I have been using Struct.new to dynamically create ruby objects that base their identity
8
+ on functionality and not on values.
9
+
10
+ ```
11
+ RegisterUser = Struct.new(:user, :params) do
12
+ # logic for registering user
13
+ end
14
+ ```
15
+
16
+ Then I looked what a Struct is: http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29
17
+
18
+ From ruby side http://www.ruby-doc.org/core-2.2.0/Struct.html
19
+
20
+ So it is an object that acts like container for data. It implements `Enumerable`.
21
+ But `RegisterUser` is not a data container, neither enumerable. So what is it?
22
+
23
+ I would say PORO (plain old ruby object).
24
+
25
+ It should be described as:
26
+
27
+ ```
28
+ RegisterUser
29
+ attr_reader :user, :params
30
+
31
+ def initialize(user, params)
32
+ @user, @params = user, params
33
+ end
34
+
35
+ # logic for registering user
36
+ end
37
+ ```
38
+
39
+ Ruby guys are lazy so we would like to type something shorter - that's provided by DefinePoro:
40
+
41
+ ```
42
+ RegisterUser = DefinePoro::Define.new(:user, :params) do
43
+ # logic for registering user
44
+ end
45
+ ```
46
+
47
+ The `DefinePoro::Define` implementation is easy and performant ruby code.
48
+
49
+ ## Should you use it?
50
+
51
+ Yes - if you are lazy to type initializers.
52
+
53
+ No - if you think that dynamic class definition could be harmful.
54
+ And I believe that in some cases it could.
55
+
56
+ ## Installation
57
+
58
+ Add this line to your application's Gemfile:
59
+
60
+ ```ruby
61
+ gem 'define-poro'
62
+ ```
63
+
64
+ And then execute:
65
+
66
+ $ bundle
67
+
68
+ Or install it yourself as:
69
+
70
+ $ gem install define-poro
71
+
72
+ ## Usage
73
+
74
+ Instead of
75
+
76
+ ```
77
+ RegisterUser
78
+ attr_reader :user, :params
79
+
80
+ def initialize(user, params)
81
+ @user, @params = user, params
82
+ end
83
+
84
+ # logic for registering user
85
+ end
86
+ ```
87
+
88
+ Define you class via
89
+
90
+ ```
91
+ RegisterUser = DefinePoro::Define.new(:user, :params) do
92
+ # logic for registering user
93
+ end
94
+ ```
95
+
96
+ ## Contributing
97
+
98
+ 1. Fork it ( https://github.com/astrauka/define-poro/fork )
99
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
100
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
101
+ 4. Ensure that you have written specs (rspec)
102
+ 5. Push to the branch (`git push origin my-new-feature`)
103
+ 6. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+
@@ -0,0 +1,5 @@
1
+ require 'define-poro/version'
2
+ require 'define-poro/define'
3
+
4
+ module DefinePoro
5
+ end
@@ -0,0 +1,17 @@
1
+ module DefinePoro
2
+ class Define
3
+ def self.new(*attributes, &block)
4
+ Class.new do
5
+ class_eval(%(
6
+ attr_reader #{attributes.map { |a| ":#{a}" }.join(', ')}
7
+
8
+ def initialize(#{attributes.join(', ')})
9
+ #{attributes.map { |a| "@#{a}=#{a}" }.join('; ')}
10
+ end
11
+ ))
12
+
13
+ class_exec &block if block_given?
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module DefinePoro
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'define-poro/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'define-poro'
8
+ spec.version = DefinePoro::VERSION
9
+ spec.authors = ['Karolis Astrauka']
10
+ spec.email = ['astrauka@gmail.com']
11
+ spec.summary = %q{Plain Old Ruby Object class builder from provided attribute list.}
12
+ spec.description = %q{Provides dynamic class builder given attributes that the ruby object
13
+ should take and class definition block.}
14
+ spec.homepage = ''
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.7'
23
+ spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'rspec', '~> 3.0'
25
+ spec.add_development_dependency 'pry', '~> 0.10'
26
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ module DefinePoro
4
+ describe Define do
5
+ describe '.new' do
6
+ let(:klass) { described_class.new(:b, :a) }
7
+
8
+ describe 'class construction properties' do
9
+ subject { klass }
10
+
11
+ it 'extends object directly' do
12
+ expect(subject.ancestors[1]).to eq Object
13
+ end
14
+
15
+ it 'supports multiple argument accessors' do
16
+ expect(subject.public_instance_methods(false)).to eq %i(b a)
17
+ end
18
+
19
+ it 'does not clash with different class arguments' do
20
+ subject
21
+ klass2 = described_class.new(:b, :c)
22
+ expect(klass.public_instance_methods(false)).to eq %i(b a)
23
+ expect(klass2.public_instance_methods(false)).to eq %i(b c)
24
+ end
25
+
26
+ it 'supports block' do
27
+ klass2 = described_class.new(:a) do
28
+ def qq
29
+ "a is #{a}"
30
+ end
31
+
32
+ def self.class_qq
33
+ 'class qq'
34
+ end
35
+ end
36
+
37
+ expect(klass2.new('1').qq).to eq 'a is 1'
38
+ expect(klass2.class_qq).to eq 'class qq'
39
+ end
40
+ end
41
+
42
+ describe 'object properties' do
43
+ subject { klass.new('b', 'a') }
44
+
45
+ it 'assigns attributes in order' do
46
+ expect(subject.a).to eq 'a'
47
+ expect(subject.b).to eq 'b'
48
+ end
49
+
50
+ it 'checks attributes count' do
51
+ expect {
52
+ klass.new('b')
53
+ }.to raise_error(ArgumentError)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,9 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'define-poro'
5
+ require 'pry'
6
+
7
+ RSpec.configure do |config|
8
+ config.order = 'random'
9
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: define-poro
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Karolis Astrauka
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-18 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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
69
+ description: |-
70
+ Provides dynamic class builder given attributes that the ruby object
71
+ should take and class definition block.
72
+ email:
73
+ - astrauka@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - ".gitignore"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - lib/define-poro.rb
84
+ - lib/define-poro/define.rb
85
+ - lib/define-poro/version.rb
86
+ - poro.gemspec
87
+ - spec/lib/define_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: ''
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.2.2
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Plain Old Ruby Object class builder from provided attribute list.
113
+ test_files:
114
+ - spec/lib/define_spec.rb
115
+ - spec/spec_helper.rb