matthewrudy-aspicious 0.1.1
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/README +54 -0
- data/Rakefile +22 -0
- data/examples/burgerking.rb +59 -0
- data/lib/aspicious.rb +1 -0
- data/lib/aspicious/watcher.rb +68 -0
- metadata +58 -0
data/README
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
Aspicious
|
2
|
+
=====================================================
|
3
|
+
|
4
|
+
Aspicious is a lightweight, simple, implementation of Aspects into Ruby.
|
5
|
+
For a more heavy handed approach see AspectR and Aquarium.
|
6
|
+
|
7
|
+
Aspicious is based on the founding principle that "aspects" is like "suspects"
|
8
|
+
and "aspicious" is like "suspicious". So it doesnt mean anything, but nevertheless is a name.
|
9
|
+
|
10
|
+
Example
|
11
|
+
=====================================================
|
12
|
+
require 'rubygems'
|
13
|
+
require 'aspicious'
|
14
|
+
|
15
|
+
class Turtle < ActiveRecord::Base
|
16
|
+
def lay_some_eggs
|
17
|
+
puts "laying these eggs good"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class EggThief < Aspicious::Watcher
|
22
|
+
watch Turtle
|
23
|
+
after :lay_some_eggs, :try_to_steal_the_eggs
|
24
|
+
|
25
|
+
def try_to_steal_the_eggs
|
26
|
+
if watchee.is_weak?
|
27
|
+
puts "I stole the eggs"
|
28
|
+
else
|
29
|
+
puts "I didnt manage to steal the eggs. Nature is safe!"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
but you can also "watch" multiple classes, and specify an :only option
|
35
|
+
|
36
|
+
class Chicken
|
37
|
+
def lay_some_eggs
|
38
|
+
puts "chickens lay eggs for everybody to eat"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class CorporateEggFarmer < Aspicious::Watcher
|
43
|
+
watch Turtle, Chicken
|
44
|
+
before :lay_some_eggs, :advertise_the_eggs, :only => Chicken
|
45
|
+
|
46
|
+
def advertise_the_eggs
|
47
|
+
puts "even though #{watchee.name}'s eggs aren't out yet, I'll start advertising them on TV. If Kerry Katona is advertising them on ITV they will surely sell?"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
BOOM!!!
|
52
|
+
Most of the power of Aspect Oriented Programming for 1% of the price
|
53
|
+
|
54
|
+
Copyright (c) 2008 [Matthew Rudy Jacobs], released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test Aspicious.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for Aspicious.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'Aspicious'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/aspicious'
|
2
|
+
class Tourist
|
3
|
+
def initialize(name)
|
4
|
+
@name = name
|
5
|
+
end
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def take_a_picture
|
9
|
+
puts "*FLASH*"
|
10
|
+
end
|
11
|
+
|
12
|
+
def enjoy!
|
13
|
+
puts "enjoyed that!"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class BurgerKing
|
18
|
+
def enjoy!
|
19
|
+
puts "enjoy your burger"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
puts "before any Aspiciousness"
|
24
|
+
tommy = Tourist.new("Tommy")
|
25
|
+
tommy.take_a_picture
|
26
|
+
|
27
|
+
class Beggar < Aspicious::Watcher
|
28
|
+
watch Tourist
|
29
|
+
after(:take_a_picture, :ask_for_money)
|
30
|
+
|
31
|
+
def ask_for_money
|
32
|
+
puts "you take picture, #{watchee.name}, you give me $1"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
puts "\n\nwith a Beggar"
|
37
|
+
tommy.take_a_picture
|
38
|
+
|
39
|
+
puts "\n\nbefore the Spoilter"
|
40
|
+
burger = BurgerKing.new
|
41
|
+
burger.enjoy!
|
42
|
+
|
43
|
+
class Spoiler < Aspicious::Watcher
|
44
|
+
watch Tourist, BurgerKing
|
45
|
+
before(:enjoy!, :spoil_it!)
|
46
|
+
after :enjoy!, :spoil_it!, :only => Tourist
|
47
|
+
after :enjoy!, :boil_it, :only => BurgerKing
|
48
|
+
def spoil_it!
|
49
|
+
puts "I always spoil everything"
|
50
|
+
end
|
51
|
+
|
52
|
+
def boil_it
|
53
|
+
puts "I always boil everything"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
puts "\n\nafter the Spoiler"
|
58
|
+
burger.enjoy!
|
59
|
+
tommy.enjoy!
|
data/lib/aspicious.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/aspicious/watcher"
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Aspicious
|
2
|
+
class Watcher
|
3
|
+
def initialize(watchee)
|
4
|
+
@watchee = watchee
|
5
|
+
end
|
6
|
+
attr_reader :watchee
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def watch(*klasses)
|
10
|
+
@watching ||= []
|
11
|
+
klasses.each do |klass|
|
12
|
+
@watching << klass
|
13
|
+
klass.class_eval <<-RUBY, __FILE__, __LINE__
|
14
|
+
unless self.instance_methods.include?('watchers')
|
15
|
+
attr_accessor :watchers
|
16
|
+
def watcher_for(klass)
|
17
|
+
self.watchers ||= []
|
18
|
+
unless watcher = self.watchers.detect{|w| w.is_a?(klass)}
|
19
|
+
watcher = klass.new(self)
|
20
|
+
self.watchers << watcher
|
21
|
+
end
|
22
|
+
return watcher
|
23
|
+
end
|
24
|
+
end
|
25
|
+
RUBY
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def before(method_to_watch, callback, options={})
|
30
|
+
do_watch(method_to_watch, callback, options, :before)
|
31
|
+
end
|
32
|
+
|
33
|
+
def after(method_to_watch, callback, options={})
|
34
|
+
do_watch(method_to_watch, callback, options, :after)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def do_watch(watch, callback, options, position)
|
40
|
+
with_method = depunctuate("#{watch}_with_watcher_executing_#{callback}_#{position}")
|
41
|
+
without_method = depunctuate("#{watch}_without_watcher_executing_#{callback}_#{position}")
|
42
|
+
call_watcher = "self.watcher_for(#{self}).#{callback}"
|
43
|
+
|
44
|
+
klasses = options[:only] || @watching
|
45
|
+
Array(klasses).each do |klass|
|
46
|
+
klass.class_eval <<-RUBY, __FILE__, __LINE__
|
47
|
+
def #{with_method}(*args, &block)
|
48
|
+
#{call_watcher if position == :before}
|
49
|
+
rtn = #{without_method}(*args, &block)
|
50
|
+
#{call_watcher if position == :after}
|
51
|
+
return rtn
|
52
|
+
end
|
53
|
+
alias :#{without_method} :#{watch}
|
54
|
+
alias :#{watch} :#{with_method}
|
55
|
+
RUBY
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def depunctuate(method_name)
|
60
|
+
method_name = method_name.to_s.dup
|
61
|
+
[['?', '_question'], ['!', '_bang'], ['=', '_equals']].each do |punctuation, replacement|
|
62
|
+
method_name.gsub!(punctuation, replacement)
|
63
|
+
end
|
64
|
+
return method_name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: matthewrudy-aspicious
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthew Rudy Jacobs
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-06 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Aspects applied to Ruby with an air of super-simplicity
|
17
|
+
email: MatthewRudyJacobs@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- README
|
26
|
+
- Rakefile
|
27
|
+
- lib/aspicious.rb
|
28
|
+
- lib/aspicious/watcher.rb
|
29
|
+
- examples/burgerking.rb
|
30
|
+
has_rdoc: true
|
31
|
+
homepage: http://github.com/matthewrudy/aspicious
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options:
|
34
|
+
- --main
|
35
|
+
- README
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: "0"
|
43
|
+
version:
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 1.2.0
|
54
|
+
signing_key:
|
55
|
+
specification_version: 2
|
56
|
+
summary: Super-simple Aspects in Ruby
|
57
|
+
test_files: []
|
58
|
+
|