procme 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 +15 -0
- data/README.md +96 -0
- data/examples/example.rb +47 -0
- data/lib/procme.rb +34 -0
- data/procme.gemspec +29 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MThlMjQxM2JhNmQ0YjZlMGFhNDQ4ZTZmODM0NDM4MDA2ZjMwYTM1ZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZmExNWYyYzI0YjM3NmM3ZjliOTRlNWRlNjgwMDJiMzQ4YzI2ZWY1Zg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YTJiZmVkZjFmMTFhN2UwODM2YWIyZjJjYTJiZDFjMDE3YTYyNzg1NjkzYzUy
|
10
|
+
NDZmYTJjYWYwOTYwNmJjYmFmYmE0MjZjYjhkZDdhZjg1NjlmZTFlZjNjNTQ2
|
11
|
+
MDMwMDdlNjNlZDQzMjMyYzAwNWE3MTZmNjc1OTY5ZWRhYmI3NzU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NzYzMTZmNGM2M2VlZmVmZGZhOWNlM2M3NjEzNjkyZDdkOTY1ZDE5ZTJjNjk2
|
14
|
+
NjZjNDU4ZDBjNDM1YTNkN2M2MmZmZjUwZjBkMmRhYTA1MTJiYWFiYTZjZTVm
|
15
|
+
NjdmZTZlMTI0YzFlYTAzMzEwN2I1NWY1MTNmM2NhMzUyOGY0ODg=
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# ProcMe
|
2
|
+
|
3
|
+
## Install
|
4
|
+
With Bundler (brand new and yet unpublished to RubyGems):
|
5
|
+
|
6
|
+
```
|
7
|
+
gem 'procme', git: 'git://github.com/zverok/procme.git'
|
8
|
+
```
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
# Giving you have
|
14
|
+
class Person < Struct.new(:name, :age, :gender)
|
15
|
+
def greet(who)
|
16
|
+
puts "#{name}: Hello, #{who}!"
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
"#<#{name}, #{gender}, #{age}>"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
people = [
|
25
|
+
Person.new('John', 30, 'male'),
|
26
|
+
Person.new('Jane', 23, 'female'),
|
27
|
+
Person.new('Jake', 48, 'male'),
|
28
|
+
Person.new('Judith', 16, 'female')
|
29
|
+
]
|
30
|
+
|
31
|
+
# With ProcMe you can:
|
32
|
+
include ProcMe
|
33
|
+
|
34
|
+
# ProcMe::fltr(method: match) - filter by attribute values/method calls:
|
35
|
+
p people.select(&fltr(gender: 'female', age: 18...30))
|
36
|
+
# => [#<Jane, female, 23>]
|
37
|
+
|
38
|
+
# ProcMe::get(:method1, :method2) - bulk get attributes
|
39
|
+
p people.map(&get(:gender, :age))
|
40
|
+
# => [["male", 30], ["female", 23], ["male", 48], ["female", 16]]
|
41
|
+
|
42
|
+
# ...which is really useful when sorting:
|
43
|
+
p people.sort_by(&get(:gender, :age))
|
44
|
+
# => [#<Judith, female, 16>, #<Jane, female, 23>, #<John, male, 30>, #<Jake, male, 48>]
|
45
|
+
|
46
|
+
# ProcMe::set(attr: value) - bulk set value:
|
47
|
+
p people.map(&set(gender: 'female'))
|
48
|
+
# => [#<John, female, 30>, #<Jane, female, 23>, #<Jake, female, 48>, #<Judith, female, 16>]
|
49
|
+
|
50
|
+
# ProcMe::call(method: args) - bulk call method with arguments:
|
51
|
+
people.each(&call(greet: 'Ellis'))
|
52
|
+
# Output:
|
53
|
+
# John: Hello, Ellis!
|
54
|
+
# Jane: Hello, Ellis!
|
55
|
+
# Jake: Hello, Ellis!
|
56
|
+
# Judith: Hello, Ellis!
|
57
|
+
```
|
58
|
+
|
59
|
+
## Rationale
|
60
|
+
|
61
|
+
Look at symple example
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
people.select{|p| p.gender == 'female'}
|
65
|
+
people.select(&fltr(gender: 'female'))
|
66
|
+
```
|
67
|
+
|
68
|
+
At a first glance, there's not a very big difference,
|
69
|
+
even in symbols count (ok, ProcMe version 1 symbol shorter :)
|
70
|
+
|
71
|
+
Yet there's one important difference: ProcMe version is
|
72
|
+
[DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). It's not
|
73
|
+
DRY for the sake of DRY, it's for better, cleaner and error-prone code.
|
74
|
+
|
75
|
+
Assume you are copying the code while rewriting it:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
aliens.select{|a| p.gender == 'female'}
|
79
|
+
# ^ bang! It was not DRY enough!
|
80
|
+
|
81
|
+
# With ProcMe
|
82
|
+
aliens.select(&fltr(gender: 'female'))
|
83
|
+
# just no repeating - no place for errors
|
84
|
+
```
|
85
|
+
|
86
|
+
In fact, the rationale it the same, as it was for inventing `Symbol#to_proc`.
|
87
|
+
|
88
|
+
ProcMe is very small and simple, without any monkey-patching of core classes.
|
89
|
+
Only four methods (`fltr`, `get`, `set`, `call`), which you can include
|
90
|
+
in any namespace or use without inclusion, for ex:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
P = ProcMe # to be short
|
94
|
+
|
95
|
+
people.select(&P.fltr(gender: 'female'))
|
96
|
+
```
|
data/examples/example.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require_relative '../lib/procme'
|
3
|
+
|
4
|
+
# Giving you have
|
5
|
+
class Person < Struct.new(:name, :age, :gender)
|
6
|
+
def greet(who)
|
7
|
+
puts "#{name}: Hello, #{who}!"
|
8
|
+
end
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"#<#{name}, #{gender}, #{age}>"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
people = [
|
16
|
+
Person.new('John', 30, 'male'),
|
17
|
+
Person.new('Jane', 23, 'female'),
|
18
|
+
Person.new('Jake', 48, 'male'),
|
19
|
+
Person.new('Judith', 16, 'female')
|
20
|
+
]
|
21
|
+
|
22
|
+
# With ProcMe you can:
|
23
|
+
include ProcMe
|
24
|
+
|
25
|
+
# ProcMe::fltr(method: match) - filter by attribute values/method calls:
|
26
|
+
p people.select(&fltr(gender: 'female', age: 18...30))
|
27
|
+
# => [#<Jane, female, 23>]
|
28
|
+
|
29
|
+
# ProcMe::get(:method1, :method2) - bulk get attributes
|
30
|
+
p people.map(&get(:gender, :age))
|
31
|
+
# => [["male", 30], ["female", 23], ["male", 48], ["female", 16]]
|
32
|
+
|
33
|
+
# ...which is really useful when sorting:
|
34
|
+
p people.sort_by(&get(:gender, :age))
|
35
|
+
# => [#<Judith, female, 16>, #<Jane, female, 23>, #<John, male, 30>, #<Jake, male, 48>]
|
36
|
+
|
37
|
+
# ProcMe::set(attr: value) - bulk set value:
|
38
|
+
p people.map(&set(gender: 'female'))
|
39
|
+
# => [#<John, female, 30>, #<Jane, female, 23>, #<Jake, female, 48>, #<Judith, female, 16>]
|
40
|
+
|
41
|
+
# ProcMe::call(method: [args]) - bulk call method with arguments:
|
42
|
+
people.each(&call(greet: 'Ellis'))
|
43
|
+
# Output:
|
44
|
+
# John: Hello, Ellis!
|
45
|
+
# Jane: Hello, Ellis!
|
46
|
+
# Jake: Hello, Ellis!
|
47
|
+
# Judith: Hello, Ellis!
|
data/lib/procme.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# ProcMe: DRY and clean blocks for your code
|
3
|
+
module ProcMe
|
4
|
+
def filter(hash)
|
5
|
+
lambda do |o|
|
6
|
+
hash.all?{|k, v| v === o.send(k)} # rubocop:disable Style/CaseEquality
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
alias_method :fltr, :filter
|
11
|
+
|
12
|
+
def set(hash)
|
13
|
+
lambda do |o|
|
14
|
+
hash.each{|k, v| o.send("#{k}=", v)}
|
15
|
+
o
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(hash)
|
20
|
+
lambda do |o|
|
21
|
+
hash.each{|k, v| o.send(k, *v)}
|
22
|
+
o
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(*array)
|
27
|
+
lambda do |o|
|
28
|
+
array.map{|v| o.send(*v)}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# now we can use both include ProcMe & no include approach
|
33
|
+
extend self # rubocop:disable Style/ModuleFunction
|
34
|
+
end
|
data/procme.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'procme'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.authors = ['Victor Shepelev']
|
5
|
+
s.email = 'zverok.offline@gmail.com'
|
6
|
+
s.homepage = 'https://github.com/zverok/procme'
|
7
|
+
|
8
|
+
s.summary = 'Useful DRY proc-s for Ruby'
|
9
|
+
s.description = <<-EOF
|
10
|
+
ProcMe provides you with methods for DRY and clean processing of
|
11
|
+
enumerables.
|
12
|
+
EOF
|
13
|
+
s.licenses = ['MIT']
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split($RS).reject do |file|
|
16
|
+
file =~ /^(?:
|
17
|
+
spec\/.*
|
18
|
+
|Gemfile
|
19
|
+
|Rakefile
|
20
|
+
|\.rspec
|
21
|
+
|\.gitignore
|
22
|
+
|\.rubocop.yml
|
23
|
+
|\.travis.yml
|
24
|
+
)$/x
|
25
|
+
end
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
|
28
|
+
s.add_development_dependency 'rubocop', '~> 0.30'
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: procme
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Victor Shepelev
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rubocop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.30'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.30'
|
27
|
+
description: ! " ProcMe provides you with methods for DRY and clean processing
|
28
|
+
of\n enumerables.\n"
|
29
|
+
email: zverok.offline@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- examples/example.rb
|
36
|
+
- lib/procme.rb
|
37
|
+
- procme.gemspec
|
38
|
+
homepage: https://github.com/zverok/procme
|
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.4.6
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: Useful DRY proc-s for Ruby
|
62
|
+
test_files: []
|