Module: Hooker

Defined in:
lib/hooker.rb,
lib/hooker/base.rb

Overview

– Copyright © 2011-2013 David Kellum

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ++

Constant Summary collapse

VERSION =

Hooker version

'1.1.0'

Class Method Summary collapse

Class Method Details

.add(k, clr = nil, &block) ⇒ Object

Add hook block by specified hook key. Will only be executed when apply, inject, or merge is later called with the same key. Multiple hook blocks for the same key will be called in the order added.



38
39
40
41
42
43
44
45
# File 'lib/hooker.rb', line 38

def add( k, clr = nil, &block )
  key = sk( k )
  clr ||= caller.first
  LOCK.synchronize do
    applied.delete( key )
    hooks[ key ] << [ block, clr.to_s ]
  end
end

.apply(key, value) ⇒ Object

Pass the specified initial value to each previously added Proc with matching key and returns the mutated value.



58
59
60
61
62
63
# File 'lib/hooker.rb', line 58

def apply( key, value )
  sync_on_hooks( key ) do |hks|
    hks.each { |hook| hook[0].call( value ) }
    value
  end
end

.check_not_appliedObject

Yields [ [ scope, key ], [ caller, … ] ] to block for each hook key added but not applied. Often this suggests a typo or other mistake by the hook Proc author.



119
120
121
122
123
124
125
126
# File 'lib/hooker.rb', line 119

def check_not_applied
  LOCK.synchronize do
    ( hooks.keys - applied ).each do |rkey|
      calls = hooks[ rkey ].map { |blk, clr| clr }
      yield( rkey, calls )
    end
  end
end

.inject(key, value = nil) ⇒ Object

Inject value (or nil) into the chain of previously added Procs, which should implement binary operations, returning desired value. Returns the last value from the last proc.



68
69
70
71
72
# File 'lib/hooker.rb', line 68

def inject( key, value = nil )
  sync_on_hooks( key ) do |hks|
    hks.inject( value ) { |v, hook| hook[0].call( v ) }
  end
end

.load_file(file) ⇒ Object

Load the specified file via Kernel.load, with a log message if set.



89
90
91
92
93
94
95
96
# File 'lib/hooker.rb', line 89

def load_file( file )
  log "Loading file #{file}"

  # Workaround for some odd load behavior when not a regular file.
  IO.read( file )

  load( file, true ) #wrap in in anonymous module
end

.log_not_appliedObject

Log results of check_not_applied, one message per not applied hook.



107
108
109
110
111
112
113
114
# File 'lib/hooker.rb', line 107

def log_not_applied
  check_not_applied do |rkey, calls|
    k = rkey.map { |s| s.inspect }.compact.join( ', ' )
    msg = "Hook #{k} was never applied. Added from:\n"
    calls.each { |cl| msg += "  - #{cl}\n" }
    log msg
  end
end

.log_with(&block) ⇒ Object

Register to yield log messages to the given block.



83
84
85
# File 'lib/hooker.rb', line 83

def log_with( &block )
  @logger = block
end

.merge(key, value = {}) ⇒ Object

Merge returned values from each added Proc to the initial value (or empty Hash).



76
77
78
79
80
# File 'lib/hooker.rb', line 76

def merge( key, value = {} )
  sync_on_hooks( key ) do |hks|
    hks.inject( value ) { |v, hook| v.merge( hook[0].call ) }
  end
end

.method_missing(method, *args, &block) ⇒ Object

Allow method setup_<foo> as alias for add( :foo )



48
49
50
51
52
53
54
# File 'lib/hooker.rb', line 48

def method_missing( method, *args, &block )
  if method.to_s =~ /^setup_(.*)$/ && args.empty?
    add( $1.to_sym, caller.first, &block )
  else
    super
  end
end

.register_config(opts) ⇒ Object

Register -c/–config flags on given OptionParser to load_file



99
100
101
102
103
# File 'lib/hooker.rb', line 99

def register_config( opts )
  opts.on( "-c", "--config FILE", "Load configuration file" ) do |file|
    load_file( file )
  end
end

.with(scp = :default) ⇒ Object

Yields self under the given scope to block.



27
28
29
30
31
32
# File 'lib/hooker.rb', line 27

def with( scp = :default )
  prior = swap_scope( scp )
  yield self
ensure
  swap_scope( prior )
end