stricter_global_usage 1.0

Sign up to get free protection for your applications and to get access to all the features.
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