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 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: []