procme 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ ```
@@ -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: []