equipment 1.4.84 → 1.4.94
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/CHANGES +12 -0
- data/Rakefile +23 -9
- data/bin/camping_command +28 -0
- data/lib/camping_boot.rb +52 -0
- data/lib/camping_ext.rb +3 -10
- data/lib/equipment.rb +10 -12
- data/lib/ext/command.rb +50 -0
- data/lib/ext/flash.rb +6 -7
- data/lib/ext/settings.rb +8 -5
- metadata +19 -9
- data/lib/more/typecast.rb +0 -288
data/CHANGES
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
= Equipment Changelog
|
|
2
2
|
|
|
3
|
+
== Version 1.4.94
|
|
4
|
+
|
|
5
|
+
This release introduces the new camping_command. It used the Camping controller
|
|
6
|
+
structure to add command-line actions to your app. All controllers that have a
|
|
7
|
+
"cmd" method are dispatched to the command-line.
|
|
8
|
+
|
|
9
|
+
* bin/camping_command : NEW console-camping apps laucher
|
|
10
|
+
* lib/ext/command.rb : NEW command thing introduced.
|
|
11
|
+
* lib/camping_boot.rb : NEW camping boot method.
|
|
12
|
+
* lib/ext/flash.rb : Fixes the logic of flash access.
|
|
13
|
+
* lib/ext/settings.rb : Conf files are now looked-up with .conf extension instead of .yaml
|
|
14
|
+
|
|
3
15
|
== Version 1.4.84
|
|
4
16
|
|
|
5
17
|
Unstable release
|
data/Rakefile
CHANGED
|
@@ -23,22 +23,32 @@ require 'rake/gempackagetask'
|
|
|
23
23
|
# Later DamageControl can bump PATCH automatically.
|
|
24
24
|
#
|
|
25
25
|
# REMEMBER TO KEEP PKG_VERSION IN SYNC WITH THE CHANGES FILE!
|
|
26
|
-
PKG_TITLE = "Equipment"
|
|
26
|
+
PKG_TITLE = "Equipment (for Camping)"
|
|
27
27
|
PKG_NAME = "equipment"
|
|
28
|
-
|
|
28
|
+
PKG_DESC = <<-EOF
|
|
29
|
+
Equipment is a set of extensions you can use with your Camping apps.
|
|
30
|
+
EOF
|
|
31
|
+
PKG_VERSION = "1.4.94"
|
|
29
32
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
|
30
33
|
PKG_FILES = FileList[
|
|
31
34
|
'[A-Z]*',
|
|
35
|
+
'bin/**/*',
|
|
32
36
|
'doc/**/*',
|
|
33
37
|
'example/**/*',
|
|
34
38
|
'lib/**/*.rb',
|
|
35
39
|
'share/**/*'
|
|
36
40
|
]
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
CLOBBER.include('test/test.log')
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
task :default => [:test]
|
|
41
45
|
|
|
46
|
+
Rake::TestTask.new(:test) do |t|
|
|
47
|
+
t.test_files = FileList[
|
|
48
|
+
'test/test_*.rb'
|
|
49
|
+
]
|
|
50
|
+
# t.warning = true
|
|
51
|
+
# t.verbose = true
|
|
42
52
|
end
|
|
43
53
|
|
|
44
54
|
# Create a task to build the RDOC documentation tree.
|
|
@@ -64,12 +74,12 @@ spec = Gem::Specification.new do |s|
|
|
|
64
74
|
|
|
65
75
|
s.name = PKG_NAME
|
|
66
76
|
s.version = PKG_VERSION
|
|
67
|
-
s.summary =
|
|
68
|
-
s.description =
|
|
69
|
-
Equipment is a set of extensions you can use with your Camping apps.
|
|
70
|
-
EOF
|
|
77
|
+
s.summary = PKG_TITLE
|
|
78
|
+
s.description = PKG_DESC
|
|
71
79
|
|
|
72
80
|
s.files = PKG_FILES.to_a
|
|
81
|
+
s.executables = ['camping_command']
|
|
82
|
+
s.bindir = 'bin'
|
|
73
83
|
s.require_path = 'lib'
|
|
74
84
|
# s.autorequire = 'meta_project'
|
|
75
85
|
|
|
@@ -88,6 +98,10 @@ spec = Gem::Specification.new do |s|
|
|
|
88
98
|
s.email = "zimba.tm@gmail.com"
|
|
89
99
|
s.homepage = "http://#{PKG_NAME}.rubyforge.org"
|
|
90
100
|
s.rubyforge_project = PKG_NAME
|
|
101
|
+
|
|
102
|
+
### Dependencies
|
|
103
|
+
|
|
104
|
+
s.add_dependency("camping", "= 1.4.157")
|
|
91
105
|
end
|
|
92
106
|
|
|
93
107
|
desc "Build Gem"
|
|
@@ -130,7 +144,7 @@ task :publish_files => [:package] do
|
|
|
130
144
|
release.user_name = ENV['RUBYFORGE_USER']
|
|
131
145
|
release.password = ENV['RUBYFORGE_PASSWORD']
|
|
132
146
|
release.files = release_files.to_a
|
|
133
|
-
release.release_name =
|
|
147
|
+
release.release_name = PKG_VERSION
|
|
134
148
|
# The rest of the options are defaults (among others, release_notes and release_changes, parsed from CHANGES)
|
|
135
149
|
end
|
|
136
150
|
end
|
data/bin/camping_command
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'camping'
|
|
4
|
+
require 'camping_boot'
|
|
5
|
+
|
|
6
|
+
usage = <<HELP
|
|
7
|
+
Usage : #{File.basename($0)} <camping_app.rb> <command> [args]
|
|
8
|
+
HELP
|
|
9
|
+
|
|
10
|
+
app = ARGV.shift
|
|
11
|
+
unless app
|
|
12
|
+
puts "ERROR : No Camping app specified"
|
|
13
|
+
puts usage
|
|
14
|
+
exit -1
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
apps = Camping.boot(app)
|
|
18
|
+
|
|
19
|
+
app = apps.first.klass
|
|
20
|
+
unless app
|
|
21
|
+
puts "ERROR : No Camping app found"; exit -1
|
|
22
|
+
end
|
|
23
|
+
unless app.respond_to? :command
|
|
24
|
+
puts "ERROR : #{app} does not support console commands"; exit -1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
app.command ARGV
|
|
28
|
+
|
data/lib/camping_boot.rb
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'camping'
|
|
2
|
+
require 'camping/reloader'
|
|
3
|
+
require 'ostruct'
|
|
4
|
+
|
|
5
|
+
module Camping
|
|
6
|
+
def self.boot(conf, *apps)
|
|
7
|
+
unless conf.kind_of? OpenStruct
|
|
8
|
+
apps.unshift conf
|
|
9
|
+
conf = OpenStruct.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Setup paths
|
|
13
|
+
if home = ENV['HOME'] # POSIX
|
|
14
|
+
conf.db = File.join(home, '.camping.db')
|
|
15
|
+
conf.rc = File.join(home, '.campingrc')
|
|
16
|
+
elsif home = ENV['APPDATA'] # MSWIN
|
|
17
|
+
conf.db = File.join(home, 'Camping.db')
|
|
18
|
+
conf.rc = File.join(home, 'Campingrc')
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Load configuration
|
|
22
|
+
if conf.rc and File.exists?( conf.rc )
|
|
23
|
+
YAML.load_file(conf.rc).each do |k,v|
|
|
24
|
+
conf.send("#{k}=", v)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Setup database
|
|
29
|
+
unless conf.database
|
|
30
|
+
unless conf.db
|
|
31
|
+
puts "!! No home directory found. Please specify a database file, see --help."; exit
|
|
32
|
+
end
|
|
33
|
+
conf.database = {:adapter => 'sqlite3', :database => conf.db}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Load apps
|
|
37
|
+
apps = apps.inject([]) do |apps, script|
|
|
38
|
+
if File.directory? script
|
|
39
|
+
apps.push(*Dir[File.join(script, '*.rb')])
|
|
40
|
+
else
|
|
41
|
+
apps << script
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
Camping::Reloader.database = conf.database
|
|
46
|
+
Camping::Reloader.log = conf.log
|
|
47
|
+
apps.map! { |script| Camping::Reloader.new(script) }
|
|
48
|
+
return apps
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
data/lib/camping_ext.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Basic camping extension
|
|
2
2
|
|
|
3
|
-
require 'camping'
|
|
3
|
+
#require 'camping'
|
|
4
4
|
require 'stringio' # used in Camping but not required
|
|
5
5
|
|
|
6
6
|
# remove some things in Camping
|
|
@@ -54,15 +54,8 @@ module CampExt
|
|
|
54
54
|
super
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
#
|
|
58
|
-
|
|
59
|
-
# This method is intended to be used by launchers that support dynamically
|
|
60
|
-
# installing and removing applications.
|
|
61
|
-
#
|
|
62
|
-
def install; false end
|
|
63
|
-
|
|
64
|
-
# See #install.
|
|
65
|
-
def uninstall; false end
|
|
57
|
+
# Not used
|
|
58
|
+
def destroy; false end
|
|
66
59
|
|
|
67
60
|
# Equips global equipments. Make sure they are included before loading your apps.
|
|
68
61
|
def self.extended(app)
|
data/lib/equipment.rb
CHANGED
|
@@ -5,12 +5,8 @@
|
|
|
5
5
|
require 'metaid'
|
|
6
6
|
require 'ruby_ext'
|
|
7
7
|
require 'ext'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
require 'camping_ext'
|
|
11
|
-
elsif not Object.autoload? :Camping
|
|
12
|
-
autoload :Camping, 'camping_ext'
|
|
13
|
-
end
|
|
8
|
+
require 'camping'
|
|
9
|
+
require 'camping_ext'
|
|
14
10
|
|
|
15
11
|
# This module provides the facilities for equipments. If included in an app,
|
|
16
12
|
# it will provide a basic set of extensions. If extended in an equipment, it
|
|
@@ -19,6 +15,8 @@ module Equipment
|
|
|
19
15
|
LIB_PATH = File.expand_path(File.dirname(__FILE__))
|
|
20
16
|
DATA_PATH = File.join(LIB_PATH, '..', 'share')
|
|
21
17
|
|
|
18
|
+
attr_accessor :debug
|
|
19
|
+
|
|
22
20
|
# Utility for equipments. Automatically sets a set of rule for importing
|
|
23
21
|
# methods, classes, class methods in your application for your extension.
|
|
24
22
|
#
|
|
@@ -56,14 +54,14 @@ module Equipment
|
|
|
56
54
|
# dependencies
|
|
57
55
|
dependencies.each { |ext| ext.equip(app) }
|
|
58
56
|
|
|
59
|
-
puts "** equipped #{self} in #{app}" if
|
|
57
|
+
puts "** equipped #{self} in #{app}" if debug
|
|
60
58
|
|
|
61
59
|
app_mods = app.constants.sort.select do |name|
|
|
62
60
|
app.const_get(name).kind_of?(Module)
|
|
63
61
|
end
|
|
64
62
|
|
|
65
|
-
puts "App Mods : #{app_mods.inspect}" if
|
|
66
|
-
puts "Ext Mods : #{constants.inspect}" if
|
|
63
|
+
puts "App Mods : #{app_mods.inspect}" if debug
|
|
64
|
+
puts "Ext Mods : #{constants.inspect}" if debug
|
|
67
65
|
|
|
68
66
|
app_mods.each do |name|
|
|
69
67
|
app_mod = app.const_get(name)
|
|
@@ -74,16 +72,16 @@ module Equipment
|
|
|
74
72
|
mod.private_instance_methods.size > 0
|
|
75
73
|
app_mod.insert(mod)
|
|
76
74
|
# app_mod.include(mod)
|
|
77
|
-
puts "Inserted : #{mod} -> #{app_mod}" if
|
|
75
|
+
puts "Inserted : #{mod} -> #{app_mod}" if debug
|
|
78
76
|
elsif mod.constants.size > 0
|
|
79
77
|
mod.transfer_classes_to(app_mod, :force)
|
|
80
|
-
puts "Cls trans : #{mod} -> #{app_mod}" if
|
|
78
|
+
puts "Cls trans : #{mod} -> #{app_mod}" if debug
|
|
81
79
|
end
|
|
82
80
|
end
|
|
83
81
|
if const_defined?("#{name}ClassMethods")
|
|
84
82
|
mod_ext = const_get("#{name}ClassMethods")
|
|
85
83
|
app_mod.extend(mod_ext)
|
|
86
|
-
puts "Extended : #{mod_ext} -> #{app_mod}" if
|
|
84
|
+
puts "Extended : #{mod_ext} -> #{app_mod}" if debug
|
|
87
85
|
end
|
|
88
86
|
end
|
|
89
87
|
end
|
data/lib/ext/command.rb
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'equipment'
|
|
2
|
+
require 'pp'
|
|
3
|
+
|
|
4
|
+
module Ext
|
|
5
|
+
module Command
|
|
6
|
+
extend Equipment
|
|
7
|
+
|
|
8
|
+
module CClassMethods
|
|
9
|
+
def command(*args)
|
|
10
|
+
self::X.M
|
|
11
|
+
args.flatten!
|
|
12
|
+
cmds=self::X.r.select{|k|k.instance_methods.include?'cmd'}
|
|
13
|
+
cmd=args.shift
|
|
14
|
+
|
|
15
|
+
# Default actions
|
|
16
|
+
unless cmd
|
|
17
|
+
cmd='default' if cmds.find{|k| /^default$/i =~ k.name.demodulize}
|
|
18
|
+
cmd='list' unless cmd
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
case cmd
|
|
22
|
+
when /^list$/i
|
|
23
|
+
cmds.each do |k|
|
|
24
|
+
puts k.name.demodulize.methodize
|
|
25
|
+
puts k.help if k.respond_to? :help
|
|
26
|
+
end
|
|
27
|
+
exit
|
|
28
|
+
else
|
|
29
|
+
k=cmds.find{|k| %r{^#{cmd.gsub('_','')}$}i =~ k.name.demodulize}
|
|
30
|
+
if not k
|
|
31
|
+
puts "ERROR : No command named '#{cmd}'"; exit -1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
out = send(:cmd, k.name.demodulize, *args).body
|
|
35
|
+
|
|
36
|
+
case out
|
|
37
|
+
when String
|
|
38
|
+
puts out
|
|
39
|
+
else
|
|
40
|
+
pp out
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
rescue => ex
|
|
44
|
+
puts "ERROR : #{ex.message}"
|
|
45
|
+
puts ex.backtrace.join("\n") if $DBG
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
data/lib/ext/flash.rb
CHANGED
|
@@ -59,17 +59,16 @@ module Ext
|
|
|
59
59
|
# Only store Strings.
|
|
60
60
|
class Flasher
|
|
61
61
|
def initialize(cookies_in, cookies_out)
|
|
62
|
-
@in, @out = cookies_in, cookies_out
|
|
62
|
+
@in, @out, @tmp = cookies_in.dup, cookies_out
|
|
63
|
+
@in.each do |k,v|
|
|
64
|
+
@in[k] = nil if v.empty?
|
|
65
|
+
end
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
def [](key)
|
|
66
69
|
key = convert_key(key)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return @in[key]
|
|
70
|
-
else
|
|
71
|
-
return nil
|
|
72
|
-
end
|
|
70
|
+
@out[key] = '' if @out.has_key? key
|
|
71
|
+
return @in[key]
|
|
73
72
|
end
|
|
74
73
|
|
|
75
74
|
def []=(key, value)
|
data/lib/ext/settings.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Ext
|
|
|
21
21
|
#
|
|
22
22
|
# setting :database, {:store=>'mysql', :hostname=>'localhost'}
|
|
23
23
|
#
|
|
24
|
-
# load_settings('your_config.
|
|
24
|
+
# load_settings('your_config.conf')
|
|
25
25
|
# end
|
|
26
26
|
#
|
|
27
27
|
# YourApp.database #=> {:store=>'mysql', :hostname=>'localhost'}
|
|
@@ -89,9 +89,9 @@ module Ext
|
|
|
89
89
|
|
|
90
90
|
# YAML config
|
|
91
91
|
configs = []
|
|
92
|
-
configs << File.join(ENV['HOME'], ".#{name}.
|
|
93
|
-
configs << File.join(ENV['APPDATA'], "#{name}.
|
|
94
|
-
configs << "/etc/#{name}.
|
|
92
|
+
configs << File.join(ENV['HOME'], ".#{name}.conf") if ENV['HOME']
|
|
93
|
+
configs << File.join(ENV['APPDATA'], "#{name}.conf") if ENV['APPDATA']
|
|
94
|
+
configs << "/etc/#{name}.conf"
|
|
95
95
|
configs.each do |conf|
|
|
96
96
|
conf = File.expand_path(conf)
|
|
97
97
|
if File.exists?(conf)
|
|
@@ -104,7 +104,7 @@ module Ext
|
|
|
104
104
|
# Ruby config
|
|
105
105
|
configs = []
|
|
106
106
|
configs << File.join(ENV['HOME'], ".#{name}.rb") if ENV['HOME']
|
|
107
|
-
configs << File.join(ENV['APPDATA'], "#{name}.
|
|
107
|
+
configs << File.join(ENV['APPDATA'], "#{name}.rb") if ENV['APPDATA']
|
|
108
108
|
configs << "/etc/#{name}.rb"
|
|
109
109
|
configs.each do |conf|
|
|
110
110
|
conf = File.expand_path(conf)
|
|
@@ -123,6 +123,9 @@ module Ext
|
|
|
123
123
|
# 'YourApp.keyname'
|
|
124
124
|
def save_settings(yaml_file=settings_path)
|
|
125
125
|
raise ArgumentError, "No settings path given" unless yaml_file
|
|
126
|
+
if File.directory?(yaml_file)
|
|
127
|
+
yaml_file = File.join(yaml_file, self.name.methodize+'.conf')
|
|
128
|
+
end
|
|
126
129
|
settings.save(yaml_file)
|
|
127
130
|
end
|
|
128
131
|
end
|
metadata
CHANGED
|
@@ -3,9 +3,9 @@ rubygems_version: 0.8.11
|
|
|
3
3
|
specification_version: 1
|
|
4
4
|
name: equipment
|
|
5
5
|
version: !ruby/object:Gem::Version
|
|
6
|
-
version: 1.4.
|
|
7
|
-
date: 2006-
|
|
8
|
-
summary:
|
|
6
|
+
version: 1.4.94
|
|
7
|
+
date: 2006-10-02 00:00:00 +02:00
|
|
8
|
+
summary: Equipment (for Camping)
|
|
9
9
|
require_paths:
|
|
10
10
|
- lib
|
|
11
11
|
email: zimba.tm@gmail.com
|
|
@@ -33,6 +33,7 @@ files:
|
|
|
33
33
|
- README
|
|
34
34
|
- LICENSE
|
|
35
35
|
- CHANGES
|
|
36
|
+
- bin/camping_command
|
|
36
37
|
- doc/structure.png
|
|
37
38
|
- doc/structure.dia
|
|
38
39
|
- lib/camping_ext.rb
|
|
@@ -40,6 +41,7 @@ files:
|
|
|
40
41
|
- lib/ruby_ext.rb
|
|
41
42
|
- lib/equipment.rb
|
|
42
43
|
- lib/mimetype_ext.rb
|
|
44
|
+
- lib/camping_boot.rb
|
|
43
45
|
- lib/ext/app_util.rb
|
|
44
46
|
- lib/ext/eruby_view.rb
|
|
45
47
|
- lib/ext/form_helpers.rb
|
|
@@ -64,7 +66,7 @@ files:
|
|
|
64
66
|
- lib/ext/active_record.rb
|
|
65
67
|
- lib/ext/view.rb
|
|
66
68
|
- lib/ext/view_slot.rb
|
|
67
|
-
- lib/
|
|
69
|
+
- lib/ext/command.rb
|
|
68
70
|
- share/js
|
|
69
71
|
- share/js/prototype.js
|
|
70
72
|
- share/js/date_ext.js
|
|
@@ -75,7 +77,7 @@ test_files: []
|
|
|
75
77
|
|
|
76
78
|
rdoc_options:
|
|
77
79
|
- --title
|
|
78
|
-
- Equipment
|
|
80
|
+
- Equipment (for Camping)
|
|
79
81
|
- --main
|
|
80
82
|
- README
|
|
81
83
|
- --line-numbers
|
|
@@ -83,11 +85,19 @@ extra_rdoc_files:
|
|
|
83
85
|
- README
|
|
84
86
|
- LICENSE
|
|
85
87
|
- CHANGES
|
|
86
|
-
executables:
|
|
87
|
-
|
|
88
|
+
executables:
|
|
89
|
+
- camping_command
|
|
88
90
|
extensions: []
|
|
89
91
|
|
|
90
92
|
requirements: []
|
|
91
93
|
|
|
92
|
-
dependencies:
|
|
93
|
-
|
|
94
|
+
dependencies:
|
|
95
|
+
- !ruby/object:Gem::Dependency
|
|
96
|
+
name: camping
|
|
97
|
+
version_requirement:
|
|
98
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: 1.4.157
|
|
103
|
+
version:
|
data/lib/more/typecast.rb
DELETED
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
# = typecast.rb
|
|
2
|
-
#
|
|
3
|
-
# == Copyright (c) 2004 Jonas Pfenniger
|
|
4
|
-
#
|
|
5
|
-
# Ruby License
|
|
6
|
-
#
|
|
7
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
|
8
|
-
# software under the same terms as Ruby.
|
|
9
|
-
#
|
|
10
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
11
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
12
|
-
# FOR A PARTICULAR PURPOSE.
|
|
13
|
-
#
|
|
14
|
-
# == Author(s)
|
|
15
|
-
#
|
|
16
|
-
# * Jonas Pfenniger
|
|
17
|
-
#
|
|
18
|
-
# == Changelog
|
|
19
|
-
#
|
|
20
|
-
# 06.06.2006 - 3v1l d4y
|
|
21
|
-
#
|
|
22
|
-
# * Removed transformation options.
|
|
23
|
-
# * Removed StringIO typecast. It is not required by default.
|
|
24
|
-
# * Added TypeCastException for better error reporting while coding.
|
|
25
|
-
#
|
|
26
|
-
# == Developer Notes
|
|
27
|
-
#
|
|
28
|
-
# TODO Consider how this might fit in with method signitures, overloading,
|
|
29
|
-
# and expiremental euphoria-like type system.
|
|
30
|
-
#
|
|
31
|
-
# TODO Look to implement to_int, to_mailtext, to_r, to_rfc822text and to_str.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# Author:: Jonas Pfenniger
|
|
35
|
-
# Copyright:: Copyright (c) 2004 Jonas Pfenniger
|
|
36
|
-
# License:: Ruby License
|
|
37
|
-
|
|
38
|
-
require 'time'
|
|
39
|
-
|
|
40
|
-
require 'facet/string/methodize'
|
|
41
|
-
require 'facet/string/modulize'
|
|
42
|
-
|
|
43
|
-
# = TypeCast
|
|
44
|
-
#
|
|
45
|
-
# Provides a generic simple type conversion utility. All the ruby core
|
|
46
|
-
# conversions are available by default.
|
|
47
|
-
#
|
|
48
|
-
# To implement a new type conversion, you have two choices :
|
|
49
|
-
#
|
|
50
|
-
# Take :
|
|
51
|
-
#
|
|
52
|
-
# class CustomType
|
|
53
|
-
# def initialize(my_var)
|
|
54
|
-
# @my_var = my_var
|
|
55
|
-
# end
|
|
56
|
-
# end
|
|
57
|
-
#
|
|
58
|
-
# * Define a to_class_name instance method
|
|
59
|
-
#
|
|
60
|
-
# class CustomType
|
|
61
|
-
# def to_string
|
|
62
|
-
# my_var.to_s
|
|
63
|
-
# end
|
|
64
|
-
# end
|
|
65
|
-
#
|
|
66
|
-
# c = CustomType.new 1234
|
|
67
|
-
# s.cast_to String => "1234" (String)
|
|
68
|
-
#
|
|
69
|
-
# * Define a from_class_name class method
|
|
70
|
-
#
|
|
71
|
-
# class CustomType
|
|
72
|
-
# def self.from_string(str)
|
|
73
|
-
# self.new(str)
|
|
74
|
-
# end
|
|
75
|
-
# end
|
|
76
|
-
#
|
|
77
|
-
# "1234".cast_to CustomType => #<CustomType:0xb7d1958c @my_var="1234">
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
# Those two methods are equivalent in the result. It was coded like that to
|
|
81
|
-
# avoid the pollution of core classes with tons of to_* methods.
|
|
82
|
-
#
|
|
83
|
-
# The standard methods to_s, to_f, to_i, to_a and to_sym are also used by
|
|
84
|
-
# this system if available.
|
|
85
|
-
#
|
|
86
|
-
# == Usage
|
|
87
|
-
#
|
|
88
|
-
# "1234".cast_to Float => 1234.0 (Float)
|
|
89
|
-
# Time.cast_from("6:30") => 1234.0 (Time)
|
|
90
|
-
#
|
|
91
|
-
# == FAQ
|
|
92
|
-
#
|
|
93
|
-
# Why didn't you name the `cast_to` method to `to` ?
|
|
94
|
-
#
|
|
95
|
-
# Even if it would make the syntax more friendly, I suspect it could cause
|
|
96
|
-
# a lot of collisions with already existing code. The goal is that each
|
|
97
|
-
# time you call cast_to, you either get your result, either a
|
|
98
|
-
# TypeCastException
|
|
99
|
-
#
|
|
100
|
-
|
|
101
|
-
class TypeCastException < Exception; end
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
|
|
105
|
-
class Object
|
|
106
|
-
|
|
107
|
-
# class TypeCastException < Exception; end
|
|
108
|
-
|
|
109
|
-
# Cast an object to another
|
|
110
|
-
#
|
|
111
|
-
# 1234.cast_to(String) => "1234"
|
|
112
|
-
#
|
|
113
|
-
def cast_to(klass)
|
|
114
|
-
klass.cast_from(self)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
# Cast on object from another
|
|
118
|
-
#
|
|
119
|
-
# String.cast_from(1234) => "1234"
|
|
120
|
-
#
|
|
121
|
-
def cast_from(object)
|
|
122
|
-
method_to = "to_#{self.name.methodize}".to_sym
|
|
123
|
-
if object.respond_to? method_to
|
|
124
|
-
retval = object.send(method_to)
|
|
125
|
-
return retval
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
method_from = "from_#{object.class.name.methodize}".to_sym
|
|
129
|
-
if respond_to? method_from
|
|
130
|
-
retval = send(method_from, object)
|
|
131
|
-
return retval
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
raise TypeCastException, "TypeCasting from #{object.class.name} to #{self.name} not supported"
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# Extend the ruby core
|
|
139
|
-
|
|
140
|
-
class Array
|
|
141
|
-
class << self
|
|
142
|
-
def cast_from(object)
|
|
143
|
-
return super
|
|
144
|
-
rescue TypeCastException
|
|
145
|
-
return object.to_a if object.respond_to? :to_a
|
|
146
|
-
raise
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
class Float
|
|
152
|
-
class << self
|
|
153
|
-
def cast_from(object)
|
|
154
|
-
return super
|
|
155
|
-
rescue TypeCastException
|
|
156
|
-
return object.to_f if object.respond_to? :to_f
|
|
157
|
-
raise
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
class Integer
|
|
163
|
-
class << self
|
|
164
|
-
def cast_from(object)
|
|
165
|
-
return super
|
|
166
|
-
rescue TypeCastException
|
|
167
|
-
return object.to_i if object.respond_to? :to_i
|
|
168
|
-
raise
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
class String
|
|
174
|
-
class << self
|
|
175
|
-
def cast_from(object)
|
|
176
|
-
return super
|
|
177
|
-
rescue TypeCastException
|
|
178
|
-
return object.to_s if object.respond_to? :to_s
|
|
179
|
-
raise
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
class Symbol
|
|
185
|
-
class << self
|
|
186
|
-
def cast_from(object)
|
|
187
|
-
return super
|
|
188
|
-
rescue TypeCastException
|
|
189
|
-
return object.to_sym if object.respond_to? :to_sym
|
|
190
|
-
raise
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
# Extensions
|
|
196
|
-
|
|
197
|
-
class Class
|
|
198
|
-
class << self
|
|
199
|
-
|
|
200
|
-
# "string".cast_to Class #=> String
|
|
201
|
-
|
|
202
|
-
def from_string(string)
|
|
203
|
-
string = string.to_s.modulize
|
|
204
|
-
base = string.sub!(/^::/, '') ? Object : (self.kind_of?(Module) ? self : self.class )
|
|
205
|
-
klass = string.split(/::/).inject(base){ |mod, name| mod.const_get(name) }
|
|
206
|
-
return klass if klass.kind_of? Class
|
|
207
|
-
nil
|
|
208
|
-
rescue
|
|
209
|
-
nil
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
alias_method :from_symbol, :from_string
|
|
213
|
-
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
class Time
|
|
218
|
-
class << self
|
|
219
|
-
def from_string(string, options={})
|
|
220
|
-
parse(string)
|
|
221
|
-
rescue
|
|
222
|
-
nil
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
# _____ _
|
|
229
|
-
# |_ _|__ ___| |_
|
|
230
|
-
# | |/ _ \/ __| __|
|
|
231
|
-
# | | __/\__ \ |_
|
|
232
|
-
# |_|\___||___/\__|
|
|
233
|
-
#
|
|
234
|
-
=begin test
|
|
235
|
-
|
|
236
|
-
require 'test/unit'
|
|
237
|
-
|
|
238
|
-
class TestClass
|
|
239
|
-
attr_accessor :my_var
|
|
240
|
-
def initialize(my_var); @my_var = my_var; end
|
|
241
|
-
|
|
242
|
-
def to_string(options={})
|
|
243
|
-
@my_var
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
class << self
|
|
247
|
-
def from_string(string, options={})
|
|
248
|
-
self.new( string )
|
|
249
|
-
end
|
|
250
|
-
end
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
class TC_TypeCast < Test::Unit::TestCase
|
|
254
|
-
|
|
255
|
-
def setup
|
|
256
|
-
@test_string = "this is a test"
|
|
257
|
-
@test_class = TestClass.new(@test_string)
|
|
258
|
-
end
|
|
259
|
-
|
|
260
|
-
def test_to_string
|
|
261
|
-
assert_equal( '1234', 1234.cast_to(String) )
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
def test_custom_to_string
|
|
265
|
-
assert_equal( @test_string, @test_class.cast_to(String) )
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
def test_custom_from_string
|
|
269
|
-
assert_equal( @test_class.my_var, @test_string.cast_to(TestClass).my_var )
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
def test_string_to_class
|
|
273
|
-
assert_equal( Test::Unit::TestCase, "Test::Unit::TestCase".cast_to(Class) )
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
def test_string_to_time
|
|
277
|
-
assert_equal( "Mon Oct 10 00:00:00 2005", "2005-10-10".cast_to(Time).strftime("%a %b %d %H:%M:%S %Y") )
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
def test_no_converter
|
|
281
|
-
"sfddsf".cast_to( ::Regexp )
|
|
282
|
-
assert(1+1==3, 'should not get here')
|
|
283
|
-
rescue TypeCastException => ex
|
|
284
|
-
assert_equal(TypeCastException, ex.class)
|
|
285
|
-
end
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
=end
|