basic_assumption 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/basic_assumption.rb +67 -4
- data/lib/basic_assumption/configuration.rb +15 -1
- data/lib/basic_assumption/default_assumption.rb +35 -6
- data/lib/basic_assumption/default_assumption/base.rb +4 -0
- data/lib/basic_assumption/default_assumption/class_resolver.rb +1 -1
- data/lib/basic_assumption/default_assumption/simple_rails.rb +13 -0
- data/lib/basic_assumption/rails.rb +6 -0
- data/lib/basic_assumption/version.rb +1 -1
- metadata +3 -3
data/lib/basic_assumption.rb
CHANGED
@@ -1,24 +1,87 @@
|
|
1
1
|
require 'basic_assumption/configuration'
|
2
2
|
require 'basic_assumption/default_assumption'
|
3
3
|
|
4
|
+
# == BasicAssumption
|
5
|
+
#
|
6
|
+
# A module that allows for a declaritive idiom that maps a name to behavior
|
7
|
+
# inside your application. It uses memoization, blocks, and the ability to
|
8
|
+
# set default behavior to clean up certain kinds of code, particularly Rails'
|
9
|
+
# controllers and views.
|
4
10
|
module BasicAssumption
|
5
|
-
|
6
|
-
|
7
|
-
|
11
|
+
# Changes the default behavior for methods created by +assume+ in the
|
12
|
+
# current class and its descendants. If a block is given, that block
|
13
|
+
# will be used as the new default. Otherwise, if +name+ is provided,
|
14
|
+
# +BasicAssumption+ will assume it refers to a snake-cased class name
|
15
|
+
# that will provide the default behavior. For details on custom defaults,
|
16
|
+
# please see the documentation for +DefaultAssumption+.
|
17
|
+
#
|
18
|
+
# === Example
|
19
|
+
#
|
20
|
+
# class WidgetController
|
21
|
+
# extend BasicAssumption
|
22
|
+
#
|
23
|
+
# default_assumption do
|
24
|
+
# Widget.find_by_id(params[:widget_id])
|
25
|
+
# log_request(current_user, params[:widget_id])
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# assume(:widget)
|
29
|
+
# end
|
30
|
+
def default_assumption(name=nil, &block)
|
31
|
+
default = block_given? ? block : name
|
32
|
+
DefaultAssumption.register(self, default)
|
8
33
|
end
|
9
34
|
|
35
|
+
# Declares a resource at the instance level by creating an instance method
|
36
|
+
# called +name+ that returns the result of +block+ if it is given or the
|
37
|
+
# default if it is not.
|
38
|
+
#
|
39
|
+
# === Example
|
40
|
+
#
|
41
|
+
# class Foo
|
42
|
+
# extend BasicAssumption
|
43
|
+
#
|
44
|
+
# assume(:cute) { 'Fuzzy kittens.' }
|
45
|
+
# assume 'assumption'
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# foo = Foo.new
|
49
|
+
# foo.cute #=> 'Fuzzy kittens.'
|
50
|
+
# foo.assumption #=> nil
|
51
|
+
#
|
52
|
+
# The first call to +assume+ creates an instance method +cute+ that
|
53
|
+
# returns the result of evaluating the block passed to it. The second call
|
54
|
+
# creates a method +assumption+ that returns the default result, which
|
55
|
+
# will be +nil+ unless the default has been overridden. See
|
56
|
+
# +default_assumption+ for details on overriding the default behavior.
|
57
|
+
#
|
58
|
+
# In both cases, the result is memoized and returned directly for
|
59
|
+
# subsequent calls.
|
10
60
|
def assume(name, &block)
|
11
61
|
define_method(name) do
|
12
62
|
@basic_assumptions ||= {}
|
13
63
|
@basic_assumptions[name] ||= if block_given?
|
14
64
|
instance_eval(&block)
|
15
65
|
else
|
16
|
-
block =
|
66
|
+
block = DefaultAssumption.resolve(self.class)
|
17
67
|
instance_exec(name, &block)
|
18
68
|
end
|
19
69
|
end
|
20
70
|
after_assumption(name)
|
21
71
|
end
|
22
72
|
|
73
|
+
# Callback that is invoked once +assume+ has created a new method.
|
74
|
+
# When BasicAssumption is used in the context of ActionController, for
|
75
|
+
# example, this callback is used to prevent the new method from being a
|
76
|
+
# visible action and to make it available in views. (See the documentation
|
77
|
+
# for +Railtie+.)
|
78
|
+
#
|
79
|
+
# class ActionController::Base
|
80
|
+
# extend BasicAssumption
|
81
|
+
# def after_assumption(name)
|
82
|
+
# helper_method(name)
|
83
|
+
# hide_action(name)
|
84
|
+
# end
|
85
|
+
# end
|
23
86
|
def after_assumption(name); end
|
24
87
|
end
|
@@ -1,9 +1,20 @@
|
|
1
1
|
module BasicAssumption
|
2
|
+
# Provides app-level configuration options for +BasicAssumption+.
|
3
|
+
# Useful in a Rails initializer or something similar.
|
2
4
|
class Configuration
|
3
|
-
|
5
|
+
# === Example
|
6
|
+
# BasicAssumption::Configuration.configure do |conf|
|
7
|
+
# conf.default_assumption = Proc.new { "I <3 GitHub." }
|
8
|
+
# end
|
9
|
+
def self.configure #:yields: config_instance
|
4
10
|
yield self.new
|
5
11
|
end
|
6
12
|
|
13
|
+
# Invoke this method if you want to have API compatibility
|
14
|
+
# with the DecentExposure library.
|
15
|
+
# (http://www.github.com/voxdolo/decent_exposure)
|
16
|
+
# Namely, this provides +expose+ and +default_exposure+ which work
|
17
|
+
# identically to +assume+ and +default_assumption+ (or rather, vice-versa.)
|
7
18
|
def emulate_exposure!
|
8
19
|
BasicAssumption.module_eval do
|
9
20
|
alias expose assume
|
@@ -11,6 +22,9 @@ module BasicAssumption
|
|
11
22
|
end
|
12
23
|
end
|
13
24
|
|
25
|
+
# Allows setting the default behavior for +assume+ calls in your app. Note
|
26
|
+
# this is an assignment, which differs from the +default_assumption+ calls
|
27
|
+
# inside of classes that extend +BasicAssumption+.
|
14
28
|
def default_assumption=(value)
|
15
29
|
BasicAssumption::DefaultAssumption.default = value
|
16
30
|
end
|
@@ -2,12 +2,41 @@ require 'basic_assumption/default_assumption/base'
|
|
2
2
|
require 'basic_assumption/default_assumption/class_resolver'
|
3
3
|
|
4
4
|
module BasicAssumption
|
5
|
+
# Handles coordinating the default behaviors available in the application
|
6
|
+
# that is using the BasicAssumption library. Classes that extend
|
7
|
+
# +BasicAssumption+ can use the +default_assumption+ method to set their
|
8
|
+
# own default, like so:
|
9
|
+
#
|
10
|
+
# class WidgetController
|
11
|
+
# default_assumption { Widget.find_by_id(123) }
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# Any calls to +assume+ inside the WidgetController class that do not also
|
15
|
+
# pass a block will use this default block as their behavior.
|
16
|
+
#
|
17
|
+
# === Providing custom default classes
|
18
|
+
#
|
19
|
+
# It is possible to pass a symbol (or string) instead of a block to the
|
20
|
+
# +default_assumption+ call. BasicAssumption out of the box will understand
|
21
|
+
# the symbol :simple_rails as an option passed to +default_assumption+,
|
22
|
+
# and will use the block provided by an instance of
|
23
|
+
# BasicAssumption::DefaultAssumption::SimpleRails as the default behavior.
|
24
|
+
#
|
25
|
+
# BasicAssumption will use the same process for any symbol passed to
|
26
|
+
# +default_assumption+. If you pass it :my_custom_default it will attempt
|
27
|
+
# to find a class BasicAssumption::DefaultAssumption::MyCustomDefault that
|
28
|
+
# provides a +block+ instance method, and use the result as the default
|
29
|
+
# behavior. See the +SimpleRails+ class for an example.
|
5
30
|
module DefaultAssumption
|
6
|
-
|
31
|
+
# Stores the +default+ as the default behavior for class +klass+ that
|
32
|
+
# will be used by calls to +assume+.
|
33
|
+
def self.register(klass, default) #:nodoc:
|
7
34
|
registry[klass.object_id] = strategy(default)
|
8
35
|
end
|
9
36
|
|
10
|
-
|
37
|
+
# Returns the default behavior used by calls to +assume+ for the class
|
38
|
+
# +klass+.
|
39
|
+
def self.resolve(klass) #:nodoc:
|
11
40
|
while !registry.has_key?(klass.object_id)
|
12
41
|
klass = klass.superclass
|
13
42
|
break if klass.nil?
|
@@ -15,15 +44,15 @@ module BasicAssumption
|
|
15
44
|
registry[klass.object_id]
|
16
45
|
end
|
17
46
|
|
18
|
-
class << self
|
19
|
-
attr_accessor :default
|
47
|
+
class << self
|
48
|
+
attr_accessor :default #:nodoc:
|
20
49
|
|
21
50
|
protected
|
22
|
-
def registry
|
51
|
+
def registry #:nodoc:
|
23
52
|
@registry ||= Hash.new { |h, k| strategy(default) }
|
24
53
|
end
|
25
54
|
|
26
|
-
def strategy(given=nil)
|
55
|
+
def strategy(given=nil) #:nodoc:
|
27
56
|
case given
|
28
57
|
when Proc
|
29
58
|
given
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module BasicAssumption
|
2
2
|
module DefaultAssumption
|
3
|
+
# Provides the default behavior out of the box for calls to
|
4
|
+
# BasicAssumption#assume. +block+ is a method that returns a Proc instance.
|
3
5
|
class Base
|
6
|
+
# Returns a proc that accepts an argument (which is, in practice, the
|
7
|
+
# name that was passed to BasicAssumption#assume) and returns +nil+.
|
4
8
|
def block
|
5
9
|
Proc.new { |name| }
|
6
10
|
end
|
@@ -1,6 +1,19 @@
|
|
1
1
|
module BasicAssumption
|
2
2
|
module DefaultAssumption
|
3
|
+
# Custom default behavior in the context of Rails.
|
3
4
|
class SimpleRails < BasicAssumption::DefaultAssumption::Base
|
5
|
+
# Returns a block that will attempt to find an instance of
|
6
|
+
# an ActiveRecord model based on the name that was given to
|
7
|
+
# BasicAssumption#assume and an id value in the parameters.
|
8
|
+
# The following two examples would be equivalent:
|
9
|
+
#
|
10
|
+
# class WidgetController < ActionController::Base
|
11
|
+
# assume :widget
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# class WidgetController < ActionController::Base
|
15
|
+
# assume(:widget) { Widget.find(params[:widget_id] || params[:id]) }
|
16
|
+
# end
|
4
17
|
def block
|
5
18
|
Proc.new do |name|
|
6
19
|
model_class = name.to_s.classify.constantize
|
@@ -2,12 +2,18 @@ if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
|
2
2
|
require 'basic_assumption/default_assumption/rails'
|
3
3
|
|
4
4
|
module BasicAssumption
|
5
|
+
# Must be required explicitly in Rails 3. Extends ActionController::Base
|
6
|
+
# with BasicAssumption, sets the default assumption behavior to be the
|
7
|
+
# :simple_rails behavior, and sets up an +after_assumption+ hook.
|
5
8
|
class Railtie < Rails::Railtie
|
6
9
|
|
7
10
|
initializer "basic_assumption.set_up_action_controller_base" do |app|
|
8
11
|
ActionController::Base.class_eval do
|
9
12
|
extend BasicAssumption
|
10
13
|
|
14
|
+
# Uses hide_action and helper_method to expose the method created
|
15
|
+
# by +assume+ as a helper inside of views, and also disallows the
|
16
|
+
# method from being called directly as a route endpoint.
|
11
17
|
def self.after_assumption(name)
|
12
18
|
hide_action name
|
13
19
|
helper_method name
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Matt Yoho
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-05-
|
17
|
+
date: 2010-05-24 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|