equipment 1.4.84 → 1.4.94
Sign up to get free protection for your applications and to get access to all the features.
- 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
|