stricter_global_usage 1.0

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.
data/.document ADDED
@@ -0,0 +1,4 @@
1
+ lib/**/*.rb
2
+ README.rdoc
3
+ ChangeLog.rdoc
4
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ html/
3
+ pkg/
4
+ vendor/cache/*.gem
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - rbx-18mode
9
+ - rbx-19mode
data/ChangeLog.rdoc ADDED
@@ -0,0 +1,4 @@
1
+ === 0.1.0 / 2012-06-10
2
+
3
+ * Initial release:
4
+
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+ gem 'rdoc', '~> 3.0'
9
+ gem 'rspec', '~> 2.4'
10
+ gem 'bundler', '~> 1.0'
11
+ gem 'rake', '~> 0.8'
12
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Mark Rushakoff
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = stricter_global_usage
2
+
3
+ {<img src="https://secure.travis-ci.org/mark-rushakoff/StricterGlobalUsage.png?branch=master" />}[http://travis-ci.org/mark-rushakoff/StricterGlobalUsage]
4
+
5
+ * {Homepage}[https://github.com/mark-rushakoff/stricter_global_usage#readme]
6
+ * {Issues}[https://github.com/mark-rushakoff/stricter_global_usage/issues]
7
+ * {Documentation}[http://rubydoc.info/gems/stricter_global_usage/frames]
8
+
9
+ == Description
10
+
11
+ There are several methods in Ruby that use a default argument of a global variable; of those, Array#join and String#split are the main two that could potentially give you problems if someone sets the corresponding global variables to something other than the default.
12
+ stricter_global_usage will raise an exception (default behavior) or give a runtime warning when you use a function and its argument falls back to the global variable - because chances are, that's not the behavior you intended.
13
+
14
+ == Features
15
+
16
+ Currently, StricterGlobalUsage wraps Array#join and String#split, applying the specified strategy if one of those methods is called without explicit arguments.
17
+
18
+ == Examples
19
+
20
+ require 'stricter_global_usage'
21
+
22
+ # default behavior:
23
+ %w(cat dog).join # => raises exception!
24
+ %w(cat dog).join($,) # => explictly uses default global variable
25
+
26
+ # warn instead of raising exceptions
27
+ ::StricterGlobalUsage::Strategy.use(:warn)
28
+ 'one two'.split # => warns, but effectively the same as `'one two'.split($;)`
29
+
30
+ # temporarily use a different strategy
31
+ ::StricterGlobalUsage::Strategy.with(:silent) do
32
+ 'one two'.split # => will not raise or warn
33
+ end
34
+ %w(cat dog).join # => will warn again
35
+
36
+ == Requirements
37
+
38
+ StricterGlobalUsage does not depend on any other gems.
39
+
40
+ == Install
41
+
42
+ $ gem install stricter_global_usage
43
+
44
+ == Copyright
45
+
46
+ Copyright (c) 2012 Mark Rushakoff
47
+
48
+ Available under the terms of the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+
5
+ begin
6
+ require 'bundler'
7
+ rescue LoadError => e
8
+ warn e.message
9
+ warn "Run `gem install bundler` to install Bundler."
10
+ exit e.status_code
11
+ end
12
+
13
+ begin
14
+ Bundler.setup(:development)
15
+ rescue Bundler::BundlerError => e
16
+ warn e.message
17
+ warn "Run `bundle install` to install missing gems."
18
+ exit e.status_code
19
+ end
20
+
21
+ require 'rake'
22
+
23
+ require 'rubygems/tasks'
24
+ Gem::Tasks.new
25
+
26
+ require 'rdoc/task'
27
+ RDoc::Task.new do |rdoc|
28
+ rdoc.title = "stricter_global_usage"
29
+ end
30
+ task :doc => :rdoc
31
+
32
+ require 'rspec/core/rake_task'
33
+ RSpec::Core::RakeTask.new
34
+
35
+ task :test => :spec
36
+ task :default => :spec
@@ -0,0 +1,11 @@
1
+ require 'stricter_global_usage/strategy'
2
+
3
+ class Array
4
+ alias_method :join_without_global_check, :join
5
+ # http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-join
6
+ # Method's argument defaults to `$,`.
7
+ def join(*args)
8
+ ::StricterGlobalUsage::Strategy.apply('Array#join') if args.length.zero?
9
+ join_without_global_check(*args)
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'stricter_global_usage/strategy'
2
+
3
+ class String
4
+ alias_method :split_without_global_check, :split
5
+
6
+ # http://ruby-doc.org/core-1.9.3/String.html#method-i-split
7
+ # Method's argument defaults to `$;`.
8
+ def split(*args)
9
+ ::StricterGlobalUsage::Strategy.apply('String#split') if args.length.zero?
10
+ split_without_global_check(*args)
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module StricterGlobalUsage
2
+ # The default error class used when StricterGlobalUsage raises an error.
3
+ class DefaultGlobalVariableUsed < RuntimeError
4
+ end
5
+ end
@@ -0,0 +1,68 @@
1
+ module StricterGlobalUsage
2
+ # The Strategy module represents the action to take when a function is called and its argument defaults to the value
3
+ # of a global variable.
4
+ #
5
+ # Consumers of StricterGlobalUsage usually will only need to use the +use+ method to specify which strategy should be
6
+ # applied when necessary.
7
+ #
8
+ # There are three built-in strategies (although consumers are free to add more through the +add+ method):
9
+ #
10
+ # * +raise+: The default strategy. Raises ::StricterGlobalUsage::DefaultGlobalVariableUsed exception.
11
+ # * +warn+: Logs the call with Kernel.warn, then continues to execute the original method.
12
+ # * +silent+: Does nothing, then continues to execute the original method.
13
+ module Strategy
14
+ @strategies = {}
15
+ @name = nil
16
+
17
+ # Apply the current strategy (warns, raises an exception, or does something else the user chose).
18
+ # When you call apply yourself, you are expected to supply the name of the method as (e.g.) 'Dog#bark'.
19
+ def self.apply(method)
20
+ @strategies[@name].call(method)
21
+ end
22
+
23
+ # Create a new strategy. When that strategy is applied, it will be passed
24
+ # in information about the call to Strategy.apply.
25
+ #
26
+ # ::StricterGlobalUsage::Strategy.add(:my_log) do |method_name|
27
+ # MyLogger.log("Used #{method_name} whose argument fell back to a global variable")
28
+ # end
29
+ def self.add(name, &block)
30
+ @strategies[name] = block
31
+ end
32
+
33
+ # Use the strategy represented by the given name.
34
+ #
35
+ # ::StricterGlobalUsage::Strategy.use(:my_log)
36
+ def self.use(name)
37
+ @name = name
38
+ end
39
+
40
+ # Use the strategy represented by the given name for the context of the given block,
41
+ # then restore the previous strategy.
42
+ #
43
+ # ::StricterGlobalUsage::Strategy.with(:silent) do
44
+ # ::SomeVendorLibrary.do_stuff
45
+ # end
46
+ def self.with(name, &block)
47
+ orig_name = @name
48
+ begin
49
+ use(name)
50
+ yield
51
+ ensure
52
+ @name = orig_name
53
+ end
54
+ end
55
+
56
+ add(:raise) do |method_name|
57
+ raise ::StricterGlobalUsage::DefaultGlobalVariableUsed.new(method_name)
58
+ end
59
+
60
+ add(:warn) do |method_name|
61
+ ::Kernel.warn("Called #{method_name} that used a default argument of a global variable")
62
+ end
63
+
64
+ add(:silent) { |_| }
65
+
66
+ use(:raise)
67
+ end
68
+ end
@@ -0,0 +1,4 @@
1
+ module StricterGlobalUsage
2
+ # stricter_global_usage version
3
+ VERSION = "1.0"
4
+ end
@@ -0,0 +1,5 @@
1
+ require 'stricter_global_usage/version'
2
+ require 'stricter_global_usage/default_global_variable_used'
3
+ require 'stricter_global_usage/core_ext/array'
4
+ require 'stricter_global_usage/core_ext/string'
5
+ require 'stricter_global_usage/strategy'
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'stricter_global_usage/core_ext/array' do
4
+ describe '#join' do
5
+ it 'applies the strategy when called without an argument' do
6
+ StricterGlobalUsage::Strategy.should_receive(:apply).once.with('Array#join')
7
+ %w(foo bar).join
8
+ end
9
+
10
+ it 'works like the example in the Ruby docs' do
11
+ StricterGlobalUsage::Strategy.should_receive(:apply).exactly(0).times
12
+ [ "a", "b", "c" ].join(nil).should == "abc"
13
+ [ "a", "b", "c" ].join("-").should == "a-b-c"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'stricter_global_usage/core_ext/string' do
4
+ describe '#split' do
5
+ it 'applies the strategy when called without an argument' do
6
+ StricterGlobalUsage::Strategy.should_receive(:apply).once.with('String#split')
7
+ '1,2,3,4,5'.split
8
+ end
9
+
10
+ it 'works like the example in the Ruby docs' do
11
+ StricterGlobalUsage::Strategy.should_receive(:apply).exactly(0).times
12
+ " now's the time".split(nil).should == ["now's", "the", "time"]
13
+ " now's the time".split(' ').should == ["now's", "the", "time"]
14
+ "1, 2.34,56, 7".split(%r{,\s*}).should == ["1", "2.34", "56", "7"]
15
+ "hello".split(%r//).should == ["h", "e", "l", "l", "o"]
16
+ "hello".split(%r//, 3).should == ["h", "e", "llo"]
17
+ "hi mom".split(%r{\s*}).should == ["h", "i", "m", "o", "m"]
18
+
19
+ "mellow yellow".split("ello").should == ["m", "w y", "w"]
20
+ "1,2,,3,4,,".split(',').should == ["1", "2", "", "3", "4"]
21
+ "1,2,,3,4,,".split(',', 4).should == ["1", "2", "", "3,4,,"]
22
+ "1,2,,3,4,,".split(',', -4).should == ["1", "2", "", "3", "4", "", ""]
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ require 'rspec'
2
+ require 'stricter_global_usage'
3
+
4
+ include StricterGlobalUsage
5
+
6
+ RSpec.configure do |config|
7
+ config.before do
8
+ ::StricterGlobalUsage::Strategy.use(:raise)
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe StricterGlobalUsage::Strategy do
4
+ describe '.use' do
5
+ it 'raises an exception with :raise' do
6
+ ::StricterGlobalUsage::Strategy.use(:raise)
7
+ expect { ::StricterGlobalUsage::Strategy.apply('Foo#bar') }.to raise_error(::StricterGlobalUsage::DefaultGlobalVariableUsed)
8
+ end
9
+
10
+ it 'warns with :warn' do
11
+ ::StricterGlobalUsage::Strategy.use(:warn)
12
+ Kernel.should_receive(:warn).once
13
+ ::StricterGlobalUsage::Strategy.apply('Foo#bar')
14
+ end
15
+ end
16
+
17
+ describe '.with' do
18
+ it 'temporarily does `use` and then reverts to the old value' do
19
+ ::StricterGlobalUsage::Strategy.use(:raise)
20
+ ::StricterGlobalUsage::Strategy.with(:silent) do
21
+ expect { ::StricterGlobalUsage::Strategy.apply('Foo#bar') }.not_to raise_error
22
+ end
23
+
24
+ expect { ::StricterGlobalUsage::Strategy.apply('Foo#bar') }.to raise_error(::StricterGlobalUsage::DefaultGlobalVariableUsed)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'stricter_global_usage'
3
+
4
+ describe StricterGlobalUsage do
5
+ it "should have a VERSION constant" do
6
+ subject.const_get('VERSION').should_not be_empty
7
+ end
8
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path('../lib/stricter_global_usage/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "stricter_global_usage"
7
+ gem.version = StricterGlobalUsage::VERSION
8
+ gem.summary = %q{Raises exceptions or runtime warnings when calling methods whose arguments default to global variables.}
9
+ gem.description = %q{Raises exceptions or runtime warnings when calling methods whose arguments default to global variables.}
10
+ gem.license = "MIT"
11
+ gem.authors = ["Mark Rushakoff"]
12
+ gem.email = "mark.rushakoff@gmail.com"
13
+ gem.homepage = "https://github.com/mark-rushakoff/stricter_global_usage#readme"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency "bundler", "~> 1.0"
21
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stricter_global_usage
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Rushakoff
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-07-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ description: Raises exceptions or runtime warnings when calling methods whose arguments
31
+ default to global variables.
32
+ email: mark.rushakoff@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .document
38
+ - .gitignore
39
+ - .rspec
40
+ - .travis.yml
41
+ - ChangeLog.rdoc
42
+ - Gemfile
43
+ - LICENSE.txt
44
+ - README.rdoc
45
+ - Rakefile
46
+ - lib/stricter_global_usage.rb
47
+ - lib/stricter_global_usage/core_ext/array.rb
48
+ - lib/stricter_global_usage/core_ext/string.rb
49
+ - lib/stricter_global_usage/default_global_variable_used.rb
50
+ - lib/stricter_global_usage/strategy.rb
51
+ - lib/stricter_global_usage/version.rb
52
+ - spec/core_ext/array_spec.rb
53
+ - spec/core_ext/string_spec.rb
54
+ - spec/spec_helper.rb
55
+ - spec/strategy_spec.rb
56
+ - spec/stricter_global_usage_spec.rb
57
+ - stricter_global_usage.gemspec
58
+ homepage: https://github.com/mark-rushakoff/stricter_global_usage#readme
59
+ licenses:
60
+ - MIT
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ segments:
72
+ - 0
73
+ hash: -224249549
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ segments:
81
+ - 0
82
+ hash: -224249549
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.23
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: Raises exceptions or runtime warnings when calling methods whose arguments
89
+ default to global variables.
90
+ test_files:
91
+ - spec/core_ext/array_spec.rb
92
+ - spec/core_ext/string_spec.rb
93
+ - spec/spec_helper.rb
94
+ - spec/strategy_spec.rb
95
+ - spec/stricter_global_usage_spec.rb