markevans-configurable 0.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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Mark Evans
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.
@@ -0,0 +1,50 @@
1
+ Configurable
2
+ ============
3
+ This is just a simple module which provides an object with a nice API for configuring it.
4
+
5
+ The best explanation is with an example.
6
+ Here we configure the `ImageProcessor` class.
7
+
8
+ First declare which attributes we want to be configurable.
9
+
10
+ class ImageProcessor
11
+
12
+ extend Configurable
13
+
14
+ configurable_attr :processing_lib # defaults to nil
15
+ configurable_attr :default_format, 'png' # defaults to 'png'
16
+
17
+ # ...other stuff...
18
+
19
+ end
20
+
21
+ Then we can configure them as we need
22
+
23
+ ImageProcessor.configure do |c|
24
+ c.processing_lib = 'imagemagick'
25
+ end
26
+
27
+ Note that we can NOT configure the ImageProcessor by just saying `ImageProcessor.processing_lib = 'imagemagick'`, the only way is via the `configure` method.
28
+
29
+ We can see what the configuration is at any time like so:
30
+
31
+ ImageProcessor.configuration # {:processing_lib => 'imagemagick', :default_format => 'png'}
32
+
33
+
34
+ Why not just use attr_accessors?
35
+ ------------------------------
36
+ It's more of a conceptual win really. By limiting the configuration of these attributes to the `configure` method, the user knows that they are dealing with the configuration of the object.
37
+ Also we are able to view the configuration with `ImageProcessor.configuration` because we've kept them separate from other accessor methods.
38
+
39
+ Why not just use a `ImageProcessor.config` hash?
40
+ ----------------------------------------------
41
+ Because after configuring an object, the rest of the code shouldn't care whether an attribute had to be configured or not (whereas it would using `ImageProcessor.config[:processing_lib]`).
42
+ This way we can decide later that an attribute should actually be configurable, and this is transparent to the rest of the code.
43
+
44
+ Install
45
+ --------
46
+ Usual way for github gems.
47
+
48
+ Copyright
49
+ --------
50
+ Copyright (c) 2009 Mark Evans. See LICENSE for details.
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "configurable"
8
+ gem.summary = "Simple module for making your class configurable"
9
+ gem.email = "mark@new-bamboo.co.uk"
10
+ gem.homepage = "http://github.com/markevans/configurable"
11
+ gem.authors = ["Mark Evans"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ rescue LoadError
16
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'spec/rake/spectask'
20
+ Spec::Rake::SpecTask.new(:spec) do |spec|
21
+ spec.libs << 'lib' << 'spec'
22
+ spec.spec_files = FileList['spec/**/*_spec.rb']
23
+ end
24
+
25
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.pattern = 'spec/**/*_spec.rb'
28
+ spec.rcov = true
29
+ end
30
+
31
+
32
+ task :default => :spec
33
+
34
+ require 'rake/rdoctask'
35
+ Rake::RDocTask.new do |rdoc|
36
+ if File.exist?('VERSION.yml')
37
+ config = YAML.load(File.read('VERSION.yml'))
38
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
39
+ else
40
+ version = ""
41
+ end
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "Configurable #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,45 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{configurable}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Mark Evans"]
9
+ s.date = %q{2009-07-01}
10
+ s.email = %q{mark@new-bamboo.co.uk}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README.markdown"
14
+ ]
15
+ s.files = [
16
+ ".document",
17
+ ".gitignore",
18
+ "LICENSE",
19
+ "README.markdown",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "configurable.gemspec",
23
+ "lib/configurable.rb",
24
+ "spec/configurable_spec.rb"
25
+ ]
26
+ s.has_rdoc = true
27
+ s.homepage = %q{http://github.com/markevans/configurable}
28
+ s.rdoc_options = ["--charset=UTF-8"]
29
+ s.require_paths = ["lib"]
30
+ s.rubygems_version = %q{1.3.1}
31
+ s.summary = %q{Simple module for making your class configurable}
32
+ s.test_files = [
33
+ "spec/configurable_spec.rb"
34
+ ]
35
+
36
+ if s.respond_to? :specification_version then
37
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
38
+ s.specification_version = 2
39
+
40
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
41
+ else
42
+ end
43
+ else
44
+ end
45
+ end
@@ -0,0 +1,42 @@
1
+ module Configurable
2
+
3
+ # Exceptions
4
+ class NothingToConfigure < StandardError; end
5
+ class BadConfigAttribute < StandardError; end
6
+
7
+ def configure(&blk)
8
+ raise NothingToConfigure, "You called configure but there are no configurable attributes" if configuration_hash.empty?
9
+ config_attributes = configuration_hash.keys
10
+ struct_class = Struct.new(*config_attributes)
11
+ struct = struct_class.new(*configuration_hash.values)
12
+ begin
13
+ yield(struct)
14
+ rescue NoMethodError => e
15
+ raise BadConfigAttribute, "You tried to configure using '#{e.name}', but the valid config attributes are #{config_attributes.map{|a| %('#{a}') }.sort.join(', ')}"
16
+ end
17
+ struct.each_pair{|k,v| configuration_hash[k] = v }
18
+ end
19
+
20
+ def configuration
21
+ configuration_hash.dup
22
+ end
23
+
24
+ private
25
+
26
+ def configurable_attr attribute, default=nil
27
+ configuration_hash[attribute] = default
28
+ class << self
29
+ self # Get the singleton class of the extended object
30
+ end.class_eval do
31
+ # Define the reader on the extended object
32
+ define_method(attribute) do
33
+ configuration_hash[attribute]
34
+ end
35
+ end
36
+ end
37
+
38
+ def configuration_hash
39
+ @configuration_hash ||= {}
40
+ end
41
+
42
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec'
2
+ require File.dirname(__FILE__) + '/../lib/configurable'
3
+
4
+ describe Configurable do
5
+
6
+ before(:each) do
7
+ class Car
8
+ extend Configurable
9
+ configurable_attr :colour
10
+ configurable_attr :top_speed, 216
11
+ def self.other_thing=(thing); end
12
+ end
13
+ end
14
+
15
+ describe "setup" do
16
+ it "should provide attr_readers for configurable attributes" do
17
+ Car.should respond_to(:colour)
18
+ end
19
+
20
+ it "should not provide attr_writers for configurable attributes" do
21
+ Car.should_not respond_to(:colour=)
22
+ end
23
+
24
+ it "should set default values for configurable attributes" do
25
+ Car.top_speed.should == 216
26
+ end
27
+
28
+ it "should set the default as nil if not specified" do
29
+ Car.colour.should be_nil
30
+ end
31
+
32
+ it "should allow specifying configurable attrs as strings" do
33
+ class Bike
34
+ extend Configurable
35
+ configurable_attr 'colour', 'rude'
36
+ end
37
+ Bike.colour.should == 'rude'
38
+ end
39
+ end
40
+
41
+
42
+ describe "configuring" do
43
+ it "should raise an error if there are no configurable attributes" do
44
+ class None; extend Configurable; end
45
+ lambda {
46
+ None.configure{|c|}
47
+ }.should raise_error(Configurable::NothingToConfigure)
48
+ end
49
+
50
+ it "should allow you to change values" do
51
+ Car.configure do |c|
52
+ c.colour = 'red'
53
+ end
54
+ Car.colour.should == 'red'
55
+ end
56
+
57
+ it "should not allow you to call other methods on the object via the configuration" do
58
+ lambda{
59
+ Car.configure do |c|
60
+ c.other_thing = 5
61
+ end
62
+ }.should raise_error(Configurable::BadConfigAttribute)
63
+ end
64
+ end
65
+
66
+ describe "getting configuration" do
67
+ it "should return the configuration as a hash" do
68
+ Car.configuration.should == {:colour => nil, :top_speed => 216}
69
+ end
70
+ it "should not allow you to change the configuration via the hash" do
71
+ Car.configuration[:top_speed] = 555
72
+ Car.top_speed.should == 216
73
+ end
74
+ end
75
+
76
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: markevans-configurable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark Evans
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-01 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: mark@new-bamboo.co.uk
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.markdown
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.markdown
30
+ - Rakefile
31
+ - VERSION
32
+ - configurable.gemspec
33
+ - lib/configurable.rb
34
+ - spec/configurable_spec.rb
35
+ has_rdoc: true
36
+ homepage: http://github.com/markevans/configurable
37
+ post_install_message:
38
+ rdoc_options:
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project:
57
+ rubygems_version: 1.2.0
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: Simple module for making your class configurable
61
+ test_files:
62
+ - spec/configurable_spec.rb