glue 0.27.0 → 0.28.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.
- data/ProjectInfo +2 -2
- data/README +1 -1
- data/Rakefile +1 -1
- data/doc/RELEASES +14 -0
- data/lib/glue.rb +4 -4
- data/lib/glue/accumulate.rb +1 -1
- data/lib/glue/aspects.rb +1 -1
- data/lib/glue/autoreload.rb +22 -14
- data/lib/glue/cache.rb +19 -0
- data/lib/glue/cache/drb.rb +49 -0
- data/lib/glue/cache/file.rb +59 -0
- data/lib/glue/cache/memcache.rb +2 -0
- data/lib/glue/cache/memory.rb +81 -0
- data/lib/glue/cache/og.rb +56 -0
- data/lib/glue/configuration.rb +7 -3
- data/lib/glue/fixture.rb +2 -2
- data/lib/glue/logger.rb +2 -2
- data/lib/glue/markup.rb +1 -1
- data/lib/glue/paramix.rb +233 -0
- data/lib/glue/property.rb +15 -9
- data/lib/glue/template.rb +1 -1
- data/lib/glue/uri.rb +1 -1
- metadata +12 -4
data/ProjectInfo
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
TITLE : &title Glue
|
|
4
4
|
NAME : &pkg glue
|
|
5
|
-
VERSION : '0.
|
|
5
|
+
VERSION : '0.28.0'
|
|
6
6
|
STATUS : beta
|
|
7
7
|
|
|
8
8
|
AUTHOR : George Moschovitis
|
|
@@ -15,7 +15,7 @@ DESCRIPTION: >
|
|
|
15
15
|
Utility methods and classes for Nitro.
|
|
16
16
|
|
|
17
17
|
DEPENDENCIES:
|
|
18
|
-
- [ facets, '=
|
|
18
|
+
- [ facets, '= 1.0.2' ]
|
|
19
19
|
- [ cmdparse, '= 2.0.0' ]
|
|
20
20
|
|
|
21
21
|
DISTRIBUTE: [ gem, tgz, zip ]
|
data/README
CHANGED
data/Rakefile
CHANGED
|
@@ -30,7 +30,7 @@ task :default => :package
|
|
|
30
30
|
# Run all tests.
|
|
31
31
|
|
|
32
32
|
Rake::TestTask.new do |t|
|
|
33
|
-
cwd = File.expand_path(File.join(File.dirname(__FILE__)
|
|
33
|
+
cwd = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
|
34
34
|
t.libs << 'test'
|
|
35
35
|
%w[glue nitro og].each do |dir|
|
|
36
36
|
t.libs << File.join(cwd, dir, 'lib')
|
data/doc/RELEASES
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
== Version 0.28.0
|
|
2
|
+
|
|
3
|
+
* New generalized caching system. The caching code is refactored
|
|
4
|
+
in a new Glue system. At the moment, caches in memory, DRb,
|
|
5
|
+
filesystem and Og are provided. A memcache version will be available
|
|
6
|
+
in the near future. The new caching system is used to implement
|
|
7
|
+
Session stores, Og caching, Fragment caching, and Application scoped
|
|
8
|
+
parameters. A useful DRb cache management script is provided to
|
|
9
|
+
manage multiple DRb caches.
|
|
10
|
+
|
|
11
|
+
* Integration of Facets 1.0.1. The new library features a better
|
|
12
|
+
API and better implementation of various features.
|
|
13
|
+
|
|
14
|
+
|
|
1
15
|
== Version 0.27.0
|
|
2
16
|
|
|
3
17
|
Various fixes and smaller improvements.
|
data/lib/glue.rb
CHANGED
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
require 'English'
|
|
12
12
|
require 'pp'
|
|
13
13
|
|
|
14
|
-
require '
|
|
15
|
-
require '
|
|
16
|
-
require '
|
|
14
|
+
require 'facet/nullclass'
|
|
15
|
+
require 'glue/paramix' # keep this before module/is
|
|
16
|
+
require 'facet/module/is'
|
|
17
17
|
|
|
18
18
|
require 'glue/property'
|
|
19
19
|
require 'glue/attribute'
|
|
@@ -36,7 +36,7 @@ module Glue
|
|
|
36
36
|
|
|
37
37
|
# The version.
|
|
38
38
|
|
|
39
|
-
Version = '0.
|
|
39
|
+
Version = '0.28.0'
|
|
40
40
|
|
|
41
41
|
# Library path.
|
|
42
42
|
|
data/lib/glue/accumulate.rb
CHANGED
data/lib/glue/aspects.rb
CHANGED
data/lib/glue/autoreload.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'facet/dir/self/recurse'
|
|
2
2
|
|
|
3
3
|
module Kernel
|
|
4
4
|
|
|
@@ -7,7 +7,11 @@ module Kernel
|
|
|
7
7
|
|
|
8
8
|
def autoreload(check_interval=10, glob = '.')
|
|
9
9
|
Thread.new(Time.now) do |start_time|
|
|
10
|
-
|
|
10
|
+
check_dirty = lambda do |file,hash,file_mtime|
|
|
11
|
+
if File.exists?(file) and (mtime = File.stat(file).mtime) > (file_mtime[file] || start_time)
|
|
12
|
+
hash[file] = mtime
|
|
13
|
+
end
|
|
14
|
+
end
|
|
11
15
|
file_mtime = {}
|
|
12
16
|
|
|
13
17
|
files = []
|
|
@@ -18,19 +22,22 @@ module Kernel
|
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
loop do
|
|
25
|
+
need_reload = Hash.new
|
|
21
26
|
sleep check_interval
|
|
22
27
|
$LOADED_FEATURES.each do |feature|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
check_dirty.call(feature,need_reload,file_mtime)
|
|
29
|
+
$LOAD_PATH.each {|lp| check_dirty.call(File.join(lp, feature),need_reload,file_mtime)}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
unless need_reload.empty?
|
|
33
|
+
$autoreload_dirty = true
|
|
34
|
+
need_reload.each_pair do |file,mtime|
|
|
35
|
+
file_mtime[file] = mtime
|
|
36
|
+
STDERR.puts "File '#{ file }' reloaded"
|
|
37
|
+
begin
|
|
38
|
+
load(file)
|
|
39
|
+
rescue Exception => e
|
|
40
|
+
STDERR.puts e.inspect
|
|
34
41
|
end
|
|
35
42
|
end
|
|
36
43
|
end
|
|
@@ -44,7 +51,8 @@ module Kernel
|
|
|
44
51
|
STDERR.puts "File '#{ file }' changed"
|
|
45
52
|
end
|
|
46
53
|
end
|
|
47
|
-
|
|
54
|
+
|
|
55
|
+
end # loop
|
|
48
56
|
|
|
49
57
|
end
|
|
50
58
|
end
|
data/lib/glue/cache.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Glue
|
|
2
|
+
|
|
3
|
+
# A general cache key.
|
|
4
|
+
|
|
5
|
+
class CacheKey
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# A general cache mechanism.
|
|
9
|
+
#
|
|
10
|
+
# This cache system was originaly developed for Nitro. It is used
|
|
11
|
+
# to cache fragments, og objects (entities), sessions, application
|
|
12
|
+
# scoped variables and more.
|
|
13
|
+
|
|
14
|
+
class Cache
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# * George Moschovitis <gm@navel.gr>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'drb'
|
|
2
|
+
|
|
3
|
+
require 'glue/cache/memory'
|
|
4
|
+
|
|
5
|
+
module Glue
|
|
6
|
+
|
|
7
|
+
# A cached backed in a DRb server.
|
|
8
|
+
#
|
|
9
|
+
# === Example
|
|
10
|
+
#
|
|
11
|
+
# This cache needs a corresponding DRb server. Here is how you
|
|
12
|
+
# can setup the standard Nitro Drb server to keep a DrbCache:
|
|
13
|
+
#
|
|
14
|
+
# require 'glue/cache/memory'
|
|
15
|
+
#
|
|
16
|
+
# class MyDrbServer < Nitro::DrbServer
|
|
17
|
+
# def setup_drb_objects
|
|
18
|
+
# ..
|
|
19
|
+
# @my_cache = SyncHash.new
|
|
20
|
+
# DRb.start_service("druby://#{my_drb_address}:#{my_drb_port}", @my_cache)
|
|
21
|
+
# ..
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# MyDrbServer.start
|
|
26
|
+
|
|
27
|
+
class DrbCache < MemoryCache
|
|
28
|
+
|
|
29
|
+
# Initialize the cache.
|
|
30
|
+
#
|
|
31
|
+
# === Options
|
|
32
|
+
#
|
|
33
|
+
# :address = The address of the DRb cache object.
|
|
34
|
+
# :port = The port of the DRb cache object.
|
|
35
|
+
|
|
36
|
+
def initialize(options = {})
|
|
37
|
+
c = {
|
|
38
|
+
:address => '127.0.0.1',
|
|
39
|
+
:port => 9080,
|
|
40
|
+
}.update(options)
|
|
41
|
+
|
|
42
|
+
@hash = DRbObject.new(nil, "druby://#{options[:address]}:#{options[:port]}")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# * George Moschovitis <gm@navel.gr>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'tmpdir'
|
|
3
|
+
|
|
4
|
+
module Glue
|
|
5
|
+
|
|
6
|
+
# TODO: safe locking of files, because Nitro can be multiprocess
|
|
7
|
+
|
|
8
|
+
class FileCache
|
|
9
|
+
|
|
10
|
+
setting :basedir, :default => "#{Dir.tmpdir}/nitro_file_cache", :doc => 'The directory to store files'
|
|
11
|
+
|
|
12
|
+
def initialize(name, keepalive = nil)
|
|
13
|
+
@path = File.join(FileCache.basedir, name)
|
|
14
|
+
@keepalive = keepalive
|
|
15
|
+
|
|
16
|
+
FileUtils.mkdir_p(@path, :mode => 0700)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def []=(k,v)
|
|
20
|
+
fn = File.join(@path, k.to_s)
|
|
21
|
+
encode_file(fn, v)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def [](k)
|
|
25
|
+
fn = File.join(@path, k.to_s)
|
|
26
|
+
return nil unless File.exists?(fn)
|
|
27
|
+
decode_file(fn)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def gc!
|
|
31
|
+
return unless @keepalive
|
|
32
|
+
|
|
33
|
+
now = Time.now
|
|
34
|
+
all.each do |fn|
|
|
35
|
+
expire_time = File.stat(fn).atime + @keepalive
|
|
36
|
+
File.delete(fn) if now > expire_time
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def all
|
|
41
|
+
Dir.glob( File.join(@path, '*' ) )
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def decode_file(fn)
|
|
47
|
+
Marshal.load( File.read(fn) )
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def encode_file(fn, value)
|
|
51
|
+
File.open(fn, "w") do |f|
|
|
52
|
+
f.chmod(0600)
|
|
53
|
+
f.write(Marshal.dump(value))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require 'facet/synchash'
|
|
2
|
+
|
|
3
|
+
require 'glue/cache'
|
|
4
|
+
|
|
5
|
+
module Glue
|
|
6
|
+
|
|
7
|
+
# A cache backed in memory.
|
|
8
|
+
#--
|
|
9
|
+
# This implementation is also the base for the Drb Cache.
|
|
10
|
+
#++
|
|
11
|
+
|
|
12
|
+
class MemoryCache < Cache
|
|
13
|
+
attr :hash
|
|
14
|
+
|
|
15
|
+
def initialize(options = {})
|
|
16
|
+
if options[:sync]
|
|
17
|
+
@hash = SyncHash
|
|
18
|
+
else
|
|
19
|
+
@hash = {}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Get an object from the cache.
|
|
24
|
+
|
|
25
|
+
def get(key, options = nil)
|
|
26
|
+
@hash[key]
|
|
27
|
+
end
|
|
28
|
+
alias_method :read, :get
|
|
29
|
+
alias_method :[], :get
|
|
30
|
+
|
|
31
|
+
# Put an object in the cache.
|
|
32
|
+
|
|
33
|
+
def set(key, value = nil, options = nil)
|
|
34
|
+
@hash[key] = value
|
|
35
|
+
end
|
|
36
|
+
alias_method :put, :set
|
|
37
|
+
alias_method :write, :set
|
|
38
|
+
alias_method :[]=, :set
|
|
39
|
+
|
|
40
|
+
# Delete an object from the cache.
|
|
41
|
+
|
|
42
|
+
def delete(key, options = nil)
|
|
43
|
+
@hash.delete(key)
|
|
44
|
+
end
|
|
45
|
+
alias_method :remove, :delete
|
|
46
|
+
|
|
47
|
+
def delete_if(&block)
|
|
48
|
+
@hash.delete_if(&block)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Perform session garbage collection. Typically this method
|
|
52
|
+
# is called from a cron like mechanism.
|
|
53
|
+
|
|
54
|
+
def gc!
|
|
55
|
+
delete_if { |key, s| s.expired? }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Return the mapping.
|
|
59
|
+
|
|
60
|
+
def mapping
|
|
61
|
+
@hash
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Return all keys in the cache.
|
|
65
|
+
|
|
66
|
+
def keys
|
|
67
|
+
@hash.keys
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Return all objects in the cache.
|
|
71
|
+
|
|
72
|
+
def all
|
|
73
|
+
@hash.values
|
|
74
|
+
end
|
|
75
|
+
alias_method :values, :all
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# * George Moschovitis <gm@navel.gr>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require 'og'
|
|
2
|
+
require 'base64'
|
|
3
|
+
|
|
4
|
+
module Glue
|
|
5
|
+
|
|
6
|
+
class OgCached
|
|
7
|
+
prop_accessor :unique_id, String, :unique => true
|
|
8
|
+
prop_accessor :expires, Time
|
|
9
|
+
prop_accessor :cache_name, String
|
|
10
|
+
prop_accessor :content
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class OgCache
|
|
14
|
+
|
|
15
|
+
def initialize(cache_name, keepalive = nil)
|
|
16
|
+
@cache_name = cache_name
|
|
17
|
+
@keepalive = keepalive
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def []=(k,v)
|
|
21
|
+
unless s = OgCached.find_by_unique_id_and_cache_name(k.to_s, @cache_name)
|
|
22
|
+
s = OgCached.new
|
|
23
|
+
s.cache_name = @cache_name
|
|
24
|
+
s.expires = Time.now + @keepalive if @keepalive
|
|
25
|
+
s.unique_id = k.to_s
|
|
26
|
+
end
|
|
27
|
+
#s.content = v.to_yaml
|
|
28
|
+
s.content = encode(v)
|
|
29
|
+
s.save
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def [](k)
|
|
33
|
+
s = OgCached.find_by_unique_id_and_cache_name(k.to_s, @cache_name) and decode(s.content)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def gc!
|
|
37
|
+
OgCached.find(:condition => ["expires < ? AND cache_name = ?", Time.now, @cache_name]).each {|s| s.delete }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def all
|
|
41
|
+
OgCached.find_by_cache_name(@cache_name)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def encode(c)
|
|
47
|
+
Base64.encode64(Marshal.dump(c))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def decode(c)
|
|
51
|
+
Marshal::load(Base64.decode64(c))
|
|
52
|
+
#s.content = YAML::load(s.content)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/glue/configuration.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require 'yaml'
|
|
2
2
|
|
|
3
|
-
require '
|
|
4
|
-
require '
|
|
3
|
+
require 'facet/kernel/constant'
|
|
4
|
+
require 'facet/synchash'
|
|
5
5
|
|
|
6
6
|
require 'glue/attribute'
|
|
7
7
|
require 'glue/flexob'
|
|
@@ -47,6 +47,10 @@ class Configuration
|
|
|
47
47
|
def to_s
|
|
48
48
|
@value.to_s
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
def <=>(other)
|
|
52
|
+
"#{owner}.#{name}" <=> "#{other.owner}.#{other.name}"
|
|
53
|
+
end
|
|
50
54
|
end
|
|
51
55
|
|
|
52
56
|
class << self
|
|
@@ -109,7 +113,7 @@ class Configuration
|
|
|
109
113
|
alias_method :[], :settings
|
|
110
114
|
|
|
111
115
|
def method_missing(sym)
|
|
112
|
-
if sym.to_s =~ /[A-Z]/ #
|
|
116
|
+
if sym.to_s =~ /[A-Z]/ # FIXME: facets's capitalized? is buggy at the moment.
|
|
113
117
|
Flexob.new(self[constant(sym)])
|
|
114
118
|
end
|
|
115
119
|
end
|
data/lib/glue/fixture.rb
CHANGED
data/lib/glue/logger.rb
CHANGED
|
@@ -43,7 +43,7 @@ class Logger
|
|
|
43
43
|
unless expr.respond_to? :to_str
|
|
44
44
|
warn "trace: Can't evaluate the given value: #{caller.first}"
|
|
45
45
|
else
|
|
46
|
-
require '
|
|
46
|
+
require 'facet/binding/self/of_caller'
|
|
47
47
|
|
|
48
48
|
Binding.of_caller do |b|
|
|
49
49
|
value = b.eval(expr.to_str)
|
|
@@ -155,7 +155,7 @@ class Logger
|
|
|
155
155
|
unless expr.respond_to? :to_str
|
|
156
156
|
warn "trace: Can't evaluate the given value: #{caller.first}"
|
|
157
157
|
else
|
|
158
|
-
require '
|
|
158
|
+
require 'facet/binding/self/of_caller'
|
|
159
159
|
|
|
160
160
|
Binding.of_caller do |b|
|
|
161
161
|
value = eval(expr.to_str, b)
|
data/lib/glue/markup.rb
CHANGED
data/lib/glue/paramix.rb
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# gmosx: replaces gems/facet_more-1.0.1/lib/facet/paramix.rb
|
|
2
|
+
# to make Nitro work, till we come up with a better solution.
|
|
3
|
+
#
|
|
4
|
+
# This is a temporary solution until the Facets version is
|
|
5
|
+
# fixed.
|
|
6
|
+
|
|
7
|
+
#--
|
|
8
|
+
# Parametric Mixins
|
|
9
|
+
#
|
|
10
|
+
# Copyright (c) 2005 Thomas Sawyer and George Moschovitis
|
|
11
|
+
#
|
|
12
|
+
# Ruby License
|
|
13
|
+
#
|
|
14
|
+
# This module is free software. You may use, modify, and/or redistribute this
|
|
15
|
+
# software under the same terms as Ruby.
|
|
16
|
+
#
|
|
17
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
19
|
+
# FOR A PARTICULAR PURPOSE.
|
|
20
|
+
#
|
|
21
|
+
# ==========================================================================
|
|
22
|
+
# Revision History
|
|
23
|
+
# --------------------------------------------------------------------------
|
|
24
|
+
# 2005-12-02 trans * Simplified into fine elegance.
|
|
25
|
+
# 2005-09-19 trans * Cleaned up and renamed.
|
|
26
|
+
# 2005-04-28 trans * Added to Calibre.
|
|
27
|
+
# ==========================================================================
|
|
28
|
+
#
|
|
29
|
+
#++
|
|
30
|
+
|
|
31
|
+
require 'facet/module/basename'
|
|
32
|
+
|
|
33
|
+
#:title: Parametric Mixins
|
|
34
|
+
#
|
|
35
|
+
# Parametric Mixins provides parameters for mixin modules.
|
|
36
|
+
# Module parameters can be set at the time of inclusion or extension,
|
|
37
|
+
# then accessed via an instance method of the same name as the included
|
|
38
|
+
# module.
|
|
39
|
+
#
|
|
40
|
+
# == Synopsis
|
|
41
|
+
#
|
|
42
|
+
# module Mixin
|
|
43
|
+
# def hello
|
|
44
|
+
# puts "Hello from #{Mixin(:name)}"
|
|
45
|
+
# end
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
48
|
+
# class MyClass
|
|
49
|
+
# include Mixin, :name => 'Ruby'
|
|
50
|
+
# end
|
|
51
|
+
#
|
|
52
|
+
# m = MyClass.new
|
|
53
|
+
# m.hello -> 'Hello from Ruby'
|
|
54
|
+
#
|
|
55
|
+
# You can view the full set of parameters via the #mixin_parameters
|
|
56
|
+
# class method, which returns a hash keyed on the included modules.
|
|
57
|
+
#
|
|
58
|
+
# MyClass.mixin_parameters #=> {Mixin=>{:name=>'Ruby'}}
|
|
59
|
+
# MyClass.mixin_parameters[Mixin] #=> {:name=>'Ruby'}
|
|
60
|
+
#
|
|
61
|
+
# To create _dynamic mixins_ you can use the #included callback
|
|
62
|
+
# method along with mixin_parameters method like so:
|
|
63
|
+
#
|
|
64
|
+
# module Mixin
|
|
65
|
+
# def included( base )
|
|
66
|
+
# parms = base.mixin_parameters[self]
|
|
67
|
+
# base.class_eval {
|
|
68
|
+
# def hello
|
|
69
|
+
# puts "Hello from #{parms(:name)}"
|
|
70
|
+
# end
|
|
71
|
+
# }
|
|
72
|
+
# end
|
|
73
|
+
# end
|
|
74
|
+
#
|
|
75
|
+
# More conveniently a new callback has been added, #included_with_parameters,
|
|
76
|
+
# which passes in the parameters in addition to the base class/module.
|
|
77
|
+
#
|
|
78
|
+
# module Mixin
|
|
79
|
+
# def included_with_parameters( base, parms )
|
|
80
|
+
# base.class_eval {
|
|
81
|
+
# def hello
|
|
82
|
+
# puts "Hello from #{parms(:name)}"
|
|
83
|
+
# end
|
|
84
|
+
# }
|
|
85
|
+
# end
|
|
86
|
+
# end
|
|
87
|
+
#
|
|
88
|
+
# We would prefer to have passed the parameters through the #included callback
|
|
89
|
+
# method itself, but implementation of such a feature is much more complicated.
|
|
90
|
+
# If a reasonable solution presents itself in the future however, we will fix.
|
|
91
|
+
#
|
|
92
|
+
# == Author(s)
|
|
93
|
+
#
|
|
94
|
+
# * George Moschovitis
|
|
95
|
+
# * Thomas Sawyer
|
|
96
|
+
#
|
|
97
|
+
|
|
98
|
+
class Module
|
|
99
|
+
|
|
100
|
+
# Store for module parameters. This is local per module
|
|
101
|
+
# and indexed on module/class included-into.
|
|
102
|
+
def mixin_parameters ; @mixin_parameters ||= {} ; end
|
|
103
|
+
|
|
104
|
+
alias_method :include_without_parameters, :include
|
|
105
|
+
|
|
106
|
+
def include(*args)
|
|
107
|
+
params = args.last.is_a?(Hash) ? args.pop : {}
|
|
108
|
+
=begin
|
|
109
|
+
for mod in args
|
|
110
|
+
mixin_parameters[mod] = params
|
|
111
|
+
define_method( mod.basename ) do |key|
|
|
112
|
+
if params.key?(key)
|
|
113
|
+
params[key]
|
|
114
|
+
else
|
|
115
|
+
super if defined?( super )
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
=end
|
|
120
|
+
r = include_without_parameters(*args)
|
|
121
|
+
for mod in args
|
|
122
|
+
mod.included_with_parameters( self, params ) if mod.respond_to?(:included_with_parameters)
|
|
123
|
+
end
|
|
124
|
+
r
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
alias_method :extend_without_parameters, :extend
|
|
128
|
+
|
|
129
|
+
def extend(*args)
|
|
130
|
+
params = args.last.is_a?(Hash) ? args.pop : nil
|
|
131
|
+
=begin
|
|
132
|
+
for mod in args
|
|
133
|
+
(class << self; self; end).class_eval do
|
|
134
|
+
mixin_parameters[mod] = params
|
|
135
|
+
define_method( mod.basename ) do |key|
|
|
136
|
+
if params.key?(key)
|
|
137
|
+
params[key]
|
|
138
|
+
else
|
|
139
|
+
super if defined?( super )
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
=end
|
|
145
|
+
r = extend_without_parameters(*args)
|
|
146
|
+
extended_with_parameters( self, params ) if method_defined?(:extended_with_parameters)
|
|
147
|
+
r
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# _____ _
|
|
155
|
+
# |_ _|__ ___| |_
|
|
156
|
+
# | |/ _ \/ __| __|
|
|
157
|
+
# | | __/\__ \ |_
|
|
158
|
+
# |_|\___||___/\__|
|
|
159
|
+
#
|
|
160
|
+
|
|
161
|
+
=begin test
|
|
162
|
+
|
|
163
|
+
require 'test/unit'
|
|
164
|
+
require 'facet/kernel/adhoc'
|
|
165
|
+
|
|
166
|
+
class TC01 < Test::Unit::TestCase
|
|
167
|
+
|
|
168
|
+
module M
|
|
169
|
+
def f
|
|
170
|
+
M(:p)
|
|
171
|
+
end
|
|
172
|
+
def self.included_with_parameters( base, parms )
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
class C
|
|
177
|
+
include M, :p => "check"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
class D
|
|
181
|
+
include M, :p => "steak"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def test_01_001
|
|
185
|
+
c = C.new
|
|
186
|
+
assert_equal( "check", c.f )
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def test_01_002
|
|
190
|
+
d = D.new
|
|
191
|
+
assert_equal( "steak", d.f )
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def test_01_003
|
|
195
|
+
assert_equal( {M=>{:p => "check"}}, C.mixin_parameters )
|
|
196
|
+
assert_equal( {M=>{:p => "steak"}}, D.mixin_parameters )
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class TC02 < Test::Unit::TestCase
|
|
203
|
+
|
|
204
|
+
module M
|
|
205
|
+
def f
|
|
206
|
+
M(:p)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
class C
|
|
211
|
+
extend M, :p => "mosh"
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
class D
|
|
215
|
+
extend M, :p => "many"
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def test_02_001
|
|
219
|
+
assert_equal( "mosh", C.f )
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def test_02_002
|
|
223
|
+
assert_equal( "many", D.f )
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def test_02_003
|
|
227
|
+
assert_equal( {M=>{:p => "mosh"}}, C.adhoc.mixin_parameters )
|
|
228
|
+
assert_equal( {M=>{:p => "many"}}, D.adhoc.mixin_parameters )
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
=end
|
data/lib/glue/property.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require '
|
|
3
|
-
require '
|
|
1
|
+
require 'facet/annotation'
|
|
2
|
+
require 'facet/inheritor'
|
|
3
|
+
require 'facet/dictionary'
|
|
4
4
|
|
|
5
5
|
require 'glue/on_included'
|
|
6
|
-
require 'og/entity'
|
|
7
6
|
require 'glue/validation'
|
|
8
|
-
require 'og/relation/all'
|
|
9
7
|
require 'glue/aspects'
|
|
8
|
+
require 'og/entity'
|
|
9
|
+
require 'og/relation/all'
|
|
10
10
|
|
|
11
11
|
# A convienience structure that holds property
|
|
12
12
|
# metadata.
|
|
@@ -71,13 +71,19 @@ class Property
|
|
|
71
71
|
|
|
72
72
|
prop_value = values[prop_name]
|
|
73
73
|
|
|
74
|
-
# to_s must be called on the prop_value incase the
|
|
74
|
+
# to_s must be called on the prop_value incase the
|
|
75
|
+
# request is IOString.
|
|
76
|
+
|
|
75
77
|
prop_value = prop_value.to_s unless prop_value.is_a?(Hash) or prop_value.is_a?(Array)
|
|
76
78
|
|
|
77
|
-
# If property is a Blob dont overwrite current
|
|
79
|
+
# If property is a Blob dont overwrite current
|
|
80
|
+
# property's data if "".
|
|
81
|
+
|
|
78
82
|
break if prop.klass == Og::Blob and prop_value.empty?
|
|
79
83
|
|
|
80
|
-
#
|
|
84
|
+
# If custom preprocessing is active then try and
|
|
85
|
+
# preprocess.
|
|
86
|
+
|
|
81
87
|
prop_value = preprocess_value(obj, prop, prop_value) if options[:preprocess]
|
|
82
88
|
|
|
83
89
|
# assign using __force_ methods.
|
|
@@ -263,7 +269,7 @@ class Module
|
|
|
263
269
|
end
|
|
264
270
|
alias :property :prop_accessor
|
|
265
271
|
|
|
266
|
-
# NITRO specific!! leave blank in
|
|
272
|
+
# NITRO specific!! leave blank in facets.
|
|
267
273
|
# TODO: factor in eval_helpers into the hook!
|
|
268
274
|
|
|
269
275
|
def self.__add_prop_hook__(m)
|
data/lib/glue/template.rb
CHANGED
|
@@ -97,7 +97,7 @@ module TemplateMixin
|
|
|
97
97
|
# (useful in xsl stylesheets)
|
|
98
98
|
# Examples: %nbsp;, %rquo;
|
|
99
99
|
|
|
100
|
-
text.gsub!(/%(
|
|
100
|
+
text.gsub!(/%(#\d+|\w+);/, '&\1;')
|
|
101
101
|
|
|
102
102
|
# Compile time ruby code. This code is evaluated when
|
|
103
103
|
# compiling the template and the result injected directly
|
data/lib/glue/uri.rb
CHANGED
metadata
CHANGED
|
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
|
3
3
|
specification_version: 1
|
|
4
4
|
name: glue
|
|
5
5
|
version: !ruby/object:Gem::Version
|
|
6
|
-
version: 0.
|
|
7
|
-
date: 2006-
|
|
6
|
+
version: 0.28.0
|
|
7
|
+
date: 2006-02-06 00:00:00 +02:00
|
|
8
8
|
summary: Utility methods and classes for Nitro.
|
|
9
9
|
require_paths:
|
|
10
10
|
- lib
|
|
@@ -15,7 +15,7 @@ description:
|
|
|
15
15
|
autorequire:
|
|
16
16
|
default_executable:
|
|
17
17
|
bindir: bin
|
|
18
|
-
has_rdoc:
|
|
18
|
+
has_rdoc: false
|
|
19
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
20
20
|
requirements:
|
|
21
21
|
- - ">"
|
|
@@ -53,16 +53,19 @@ files:
|
|
|
53
53
|
- lib/glue/sanitize.rb
|
|
54
54
|
- lib/glue/property.rb
|
|
55
55
|
- lib/glue/on_included.rb
|
|
56
|
+
- lib/glue/cache
|
|
56
57
|
- lib/glue/html.rb
|
|
57
58
|
- lib/glue/mailer.rb
|
|
58
59
|
- lib/glue/mail.rb
|
|
59
60
|
- lib/glue/logger.rb
|
|
60
61
|
- lib/glue/attribute.rb
|
|
62
|
+
- lib/glue/paramix.rb
|
|
61
63
|
- lib/glue/flexob.rb
|
|
62
64
|
- lib/glue/fixture.rb
|
|
63
65
|
- lib/glue/builder.rb
|
|
64
66
|
- lib/glue/configuration.rb
|
|
65
67
|
- lib/glue/expirable.rb
|
|
68
|
+
- lib/glue/cache.rb
|
|
66
69
|
- lib/glue/aspects.rb
|
|
67
70
|
- lib/glue/markup.rb
|
|
68
71
|
- lib/glue/accumulate.rb
|
|
@@ -70,6 +73,11 @@ files:
|
|
|
70
73
|
- lib/glue/builder/xml.rb
|
|
71
74
|
- lib/glue/mailer/outgoing.rb
|
|
72
75
|
- lib/glue/mailer/incoming.rb
|
|
76
|
+
- lib/glue/cache/file.rb
|
|
77
|
+
- lib/glue/cache/og.rb
|
|
78
|
+
- lib/glue/cache/memcache.rb
|
|
79
|
+
- lib/glue/cache/memory.rb
|
|
80
|
+
- lib/glue/cache/drb.rb
|
|
73
81
|
- lib/html/tokenizer.rb
|
|
74
82
|
- lib/html/version.rb
|
|
75
83
|
- lib/html/document.rb
|
|
@@ -121,7 +129,7 @@ dependencies:
|
|
|
121
129
|
requirements:
|
|
122
130
|
- - "="
|
|
123
131
|
- !ruby/object:Gem::Version
|
|
124
|
-
version:
|
|
132
|
+
version: 1.0.2
|
|
125
133
|
version:
|
|
126
134
|
- !ruby/object:Gem::Dependency
|
|
127
135
|
name: cmdparse
|