attach_function 0.1.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13ee26dfe343552e2bc5fd7807e08afab1a03bd4
4
- data.tar.gz: 93789012ea84d1177721e0ec6b851e473816bee4
3
+ metadata.gz: 11e67fe07ac303c8f2c3fc3ca1ca130185dc91ac
4
+ data.tar.gz: 45b2be4c31976b5e5fccf18b49485a4ea06dad91
5
5
  SHA512:
6
- metadata.gz: 132e09d24a243b0624269cc0d22dfab4959f8f36371d007acf829a0d3a4449d7153da4661d18c3c8a1ab6504da7096df9edb28207ed76cb7705d7fafd93c88fc
7
- data.tar.gz: 41cb13978e31d6aa13df7188376a4603df519a04e93d890726d7f0ea9bc42399bffc121488674452f956aaa5b022c8fbd383735ef403dd07d0d02aac5d6b93f7
6
+ metadata.gz: b752860396416ac322fce4b49ba243a3ad778d316bb046d79d8392b3a1dca2aa697fb7870be5c2aa6dd43e91187154dcc5e75af79f4f4b3590f019786b203b7b
7
+ data.tar.gz: 74ee96c15175952138ee4cef1ad71a7726058be0b01e2c8e64ca2004a47562b0019332126f817c50bc7861dffe64e4d7ea9dd4e889e1e5a50db343c3249bcc9d
data/README.md CHANGED
@@ -31,15 +31,39 @@ Numeric.include(Math::MethodVersions)
31
31
  p "3.14.sin = #{3.14.sin}"
32
32
  p "10.log = #{10.log10}"
33
33
  p "4.sqrt = #{4.sqrt}"
34
- ```
35
34
 
36
35
  #The functionality that has been added to Numeric in this way is contained in the Math::MethodVersions mixin.
37
36
  #I consider this much nicer than rudely monkepatching methods right onto a core class.
38
37
  #This way, library users can see (in pry, for example, or via introspection) where a certain added method came from, and possibly filter it out.
39
38
  #(Ruby doesn't currently support unmixing).
40
39
 
40
+ ```
41
+
41
42
 
42
43
  See the specs and the example folder for more examples.
44
+
45
+ ## Versioning
46
+
47
+ ### Version number for machines
48
+
49
+ This gem uses a slightly modified version of the **SemVer** specification, namely:
50
+ ```ruby
51
+ spec.version = "BREAKING.PATCHES.NONBREAKING"
52
+ ```
53
+ You can use this versioning with your dependency tools, only you have a somewhat stronger guarantees that your
54
+ code won't break if you limit yourself to the third number, but you need to allow second level updates in order to
55
+ get (security and other) patches.
56
+
57
+ ### Version number for humans
58
+ Since the above-described type of versioning doesn't tell you anything about the functional state of the gem (you can go from a "hello world" to a full blown operating system
59
+ without making a breaking change, as long as your operating system prints "hello world" to the screen) (SemVer, when used correctly, doesn't tell anything about the functional state of a software package either)
60
+ A second human-friendly version number can be found in `spec.metadata[:human_version]`.
61
+
62
+ The magnitude of this version number shall be made to correspond to actual functional changes in the software.
63
+ If I've worked a lot on the package, I'll make it move a lot, but unless I've made breaking changes, I'll stick to only moving the third number in the `spec.version` version.
64
+ This number is for you. If you see it increase a lot, it probably means much more new goodies, but is less strictly defined then the version number for the machine. (I reserve the right to later change the way I change this number).
65
+
66
+
43
67
  ## Installation
44
68
 
45
69
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -2,6 +2,5 @@ require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
-
6
5
  task :default => :spec
7
6
 
data/VERSIONING.md ADDED
@@ -0,0 +1,22 @@
1
+ # Versioning
2
+
3
+ ## Version number for machines
4
+
5
+ This gem uses a slightly modified version of the **SemVer** specification, namely:
6
+ ```ruby
7
+ spec.version = "BREAKING.PATCHES.NONBREAKING"
8
+ ```
9
+ You can use this versioning with your dependency tools, only you have a somewhat stronger guarantees that your
10
+ code won't break if you limit yourself to the third number, but you need to allow second level updates in order to
11
+ get (security and other) patches.
12
+
13
+ ## Version number for humans
14
+ Since the above-described type of versioning doesn't tell you anything about the functional state of the gem (you can go from a "hello world" to a full blown operating system
15
+ without making a breaking change, as long as your operating system prints "hello world" to the screen) (SemVer, when used correctly, doesn't tell anything about the functional state of a software package either)
16
+ A second human-friendly version number can be found in `spec.metadata[:human_version]`.
17
+
18
+ The magnitude of this version number shall be made to correspond to actual functional changes in the software.
19
+ If I've worked a lot on the package, I'll make it move a lot, but unless I've made breaking changes, I'll stick to only moving the third number in the `spec.version` version.
20
+ This number is for you. If you see it increase a lot, it probably means much more new goodies, but is less strictly defined then the version number for the machine. (I reserve the right to later change the way I change this number).
21
+
22
+
Binary file
@@ -5,7 +5,8 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'ostruct'
6
6
 
7
7
  gem = OpenStruct.new
8
- gem.name = File.basename(File.dirname(__FILE__))
8
+ gem.name = File.basename(File.expand_path(File.dirname(__FILE__)))
9
+
9
10
  require "#{gem.name}/version"
10
11
  gem.module = AttachFunction
11
12
 
@@ -13,6 +14,7 @@ Gem::Specification.new do |spec|
13
14
 
14
15
  spec.name = gem.name
15
16
  spec.version = (gem.module)::VERSION
17
+ #spec.metadata[:human_version] = (gem.module)::HUMAN_VERSION
16
18
  spec.summary = %q{Macro to attach a module function to an object by fixing its first argument to self}
17
19
  spec.description = %q{Macro to attach a module function to an object by fixing its first argument to self}
18
20
 
@@ -26,10 +28,12 @@ Gem::Specification.new do |spec|
26
28
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
27
29
  spec.require_paths = ["lib"]
28
30
 
29
- spec.add_development_dependency "bundler", "~> 1.7"
31
+ #spec.add_development_dependency "bundler", "~> 1.7"
30
32
  spec.add_development_dependency "rake", "~> 10.0"
31
33
  spec.add_development_dependency "rspec"
32
34
  spec.add_development_dependency "guard", "2.12"
33
35
  spec.add_development_dependency "guard-rspec"
36
+ #spec.add_development_dependency "listen"
37
+ #spec.add_development_dependency "highline"
34
38
  spec.add_development_dependency "guard-bundler"
35
39
  end
@@ -1,3 +1,4 @@
1
1
  module AttachFunction
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.2"
3
+ HUMAN_VERSION = "1.0.3"
3
4
  end
@@ -1,27 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- coding: utf-8 -*-
3
3
  module AttachFunction
4
- #
5
- #attach_function defines new methods that are partial applications of a target function where the first argument to the target function gets fixed to self.
6
- #
7
- #The name of the newly defined method will be the basename of the target function (the module path gets stripped) or a user-specified name.
8
- #The receiver of relatively specified parameter functions will be the current module, if a user-specified name is given and
9
- #the user-specified name is not the same as the basename of the target function, or the enclosing module, if no-user specified name is provided or
10
- #if the user-specified name is the same as the basename of the parameter.
11
- #
12
- #Usage:
13
- #
14
- #module MyModule
15
- # def function_method1(arg1, arg2); end
16
- # def function_method2(arg1); end
17
- #
18
- # module MethodVersions
19
- # extend Attachmethod
20
- # attach_function :function_method1
21
- # attach_function :function_method2
22
- # end
23
- #
24
- #See the specs and the example folder for more examples.
25
4
 
26
5
  def _receiver_and_message(method_name, function_symbol)
27
6
  #Parse the function symbol to get the receiver and the function's basename
@@ -36,15 +15,41 @@ module AttachFunction
36
15
  #Can't send to self if method_name == function_method (or it will recurse and crash):
37
16
  # send it to the outer module/class, if there's no outer module, send it to Object
38
17
  if (method_name ||= function_method) == function_method
39
- receiver = self.name
40
- outer_module = receiver.rpartition('::').first
41
- receiver = outer_module == "" ? Object : eval(outer_module)
18
+ receiver = Object.const_get(outer_module_name(name))
42
19
  end
43
20
  end
44
21
 
45
22
  return [ receiver, function_method ]
46
23
  end
47
24
 
25
+ #Give a fully qualified name of the outer module for a name assumed to be fully qualified
26
+ #(:: is prepended unless it's already there)
27
+ def outer_module_name(name)
28
+ outer_module = name.rpartition('::').first
29
+ outer_module.sub!(/^::/,'')
30
+ return outer_module == "" ? '::Object' : ('::'+outer_module)
31
+ end
32
+
33
+ #attach_function defines new methods that are partial applications of a target function where the first argument to the target function gets fixed to self.
34
+ #
35
+ #The name of the newly defined method will be the basename of the target function (the module path gets stripped) or a user-specified name.
36
+ #The receiver of relatively specified parameter functions will be the current module, if a user-specified name is given and
37
+ #the user-specified name is not the same as the basename of the target function, or the enclosing module, if no-user specified name is provided or
38
+ #if the user-specified name is the same as the basename of the parameter.
39
+ #
40
+ #Usage:
41
+ #
42
+ #module MyModule
43
+ # def function_method1(arg1, arg2); end
44
+ # def function_method2(arg1); end
45
+ #
46
+ # module MethodVersions
47
+ # extend Attachmethod
48
+ # attach_function :function_method1
49
+ # attach_function :function_method2
50
+ # end
51
+ #
52
+ #See the specs and the example folder for more examples.
48
53
  def attach_function(method_name = nil, function_symbol)
49
54
  receiver, message = _receiver_and_message(method_name, function_symbol)
50
55
 
@@ -56,4 +61,13 @@ module AttachFunction
56
61
  receiver.send(message, self, *args)
57
62
  end
58
63
  end
64
+
65
+ #Attaches all uninherited (by default, pass true to change that) public class methods
66
+ #of the enclosing module or of Object
67
+ def attach_outer_class_methods(inherited = false)
68
+ outer_module = Object.const_get(outer_module_name(name))
69
+ outer_module.methods(inherited).each do |m|
70
+ attach_function m
71
+ end
72
+ end
59
73
  end
@@ -27,6 +27,21 @@ describe AttachFunction do
27
27
  it 'has a version number' do
28
28
  expect(AttachFunction::VERSION).not_to be nil
29
29
  end
30
+ describe "#_outer_module_name" do
31
+ extend AttachFunction
32
+ {
33
+ '::A::M' => "::A",
34
+ 'A::m' => "::A",
35
+ '::A::B::M' => "::A::B",
36
+ '::A' => "::Object",
37
+ 'A' => "::Object"
38
+ }.each_pair do |k,answers|
39
+ it "should resolve #{k} to #{answers.inspect}" do
40
+ extend AttachFunction
41
+ expect(outer_module_name(k)).to eq(answers)
42
+ end
43
+ end
44
+ end
30
45
  it "should define an instance method named 'attach_function'" do
31
46
  expect(subject.instance_methods(false)).to include(:attach_function)
32
47
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attach_function
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Petr Skocik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-01 00:00:00.000000000 Z
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
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
13
  - !ruby/object:Gem::Dependency
28
14
  name: rake
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -109,6 +95,8 @@ files:
109
95
  - Guardfile
110
96
  - README.md
111
97
  - Rakefile
98
+ - VERSIONING.md
99
+ - attach_function-0.1.2.gem
112
100
  - attach_function.gemspec
113
101
  - examples/enclosing_scope.rb
114
102
  - lib/attach_function.rb
@@ -135,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
123
  version: '0'
136
124
  requirements: []
137
125
  rubyforge_project:
138
- rubygems_version: 2.2.1
126
+ rubygems_version: 2.2.2
139
127
  signing_key:
140
128
  specification_version: 4
141
129
  summary: Macro to attach a module function to an object by fixing its first argument