equipment 0.1.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 +55 -0
- data/README +67 -0
- data/examples/basicauthtest.rb +59 -0
- data/examples/erubytest.rb +36 -0
- data/examples/flashtest.rb +46 -0
- data/examples/index.erb +9 -0
- data/examples/mounttest.rb +34 -0
- data/examples/ogtest.rb +41 -0
- data/examples/patchestest.rb +40 -0
- data/examples/sendfiletest.rb +29 -0
- data/lib/equipment.rb +195 -0
- data/lib/ext/app_util.rb +28 -0
- data/lib/ext/basic_auth.rb +71 -0
- data/lib/ext/controls.rb +26 -0
- data/lib/ext/eruby_view.rb +83 -0
- data/lib/ext/flash.rb +81 -0
- data/lib/ext/forms.rb +22 -0
- data/lib/ext/forward.rb +70 -0
- data/lib/ext/js_helpers.rb +50 -0
- data/lib/ext/mount.rb +152 -0
- data/lib/ext/og.rb +95 -0
- data/lib/ext/og_scaffold.rb +119 -0
- data/lib/ext/og_session.rb +76 -0
- data/lib/ext/patches.rb +130 -0
- data/lib/ext/ressource.rb +88 -0
- data/lib/ext/security.rb +83 -0
- data/lib/ext/sendfile.rb +84 -0
- data/lib/ext/template_view.rb +72 -0
- data/lib/ext/use_helper.rb +83 -0
- data/lib/ext/xml_view.rb +47 -0
- metadata +78 -0
data/ProjectInfo
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- %YAML:1.0
|
2
|
+
|
3
|
+
title : &title Equipment
|
4
|
+
name : &pkg equipment
|
5
|
+
version : '0.1.0'
|
6
|
+
status : alpha
|
7
|
+
|
8
|
+
author : Jonas Pfenniger
|
9
|
+
email : &email zimba.tm@gmail.com
|
10
|
+
username : &username zimbatm
|
11
|
+
homepage : "http://equipment.rubyforge.org"
|
12
|
+
|
13
|
+
summary : Camping equipments
|
14
|
+
|
15
|
+
description: >
|
16
|
+
Equipment is a set of ready to use extensions for Camping.
|
17
|
+
|
18
|
+
rubyforge:
|
19
|
+
project: *pkg
|
20
|
+
username: zimbatm
|
21
|
+
|
22
|
+
dependencies:
|
23
|
+
- [ camping, '>= 1.4.2' ]
|
24
|
+
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
#=================================================
|
28
|
+
# Unremark and use as needed. Often defaults
|
29
|
+
# are sufficiant and need not specify
|
30
|
+
# extra parameters.
|
31
|
+
#=================================================
|
32
|
+
|
33
|
+
package: !!package
|
34
|
+
distribute : [ gem, zip, tgz ] # tgz zip deb tar.bzip2 gem
|
35
|
+
exclude : [ _darcs, doc, web ]
|
36
|
+
|
37
|
+
rdoc: !!rdoc
|
38
|
+
|
39
|
+
test: !!test
|
40
|
+
|
41
|
+
release: !!release
|
42
|
+
host : rubyforge.org
|
43
|
+
username : *username
|
44
|
+
project : *pkg
|
45
|
+
groupid : 811
|
46
|
+
package : *title
|
47
|
+
dir : 'dist'
|
48
|
+
|
49
|
+
publish: !!publish
|
50
|
+
target : rubyforge
|
51
|
+
type : web
|
52
|
+
host : rubyforge.org
|
53
|
+
username : *username
|
54
|
+
dir : web
|
55
|
+
|
data/README
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
== Equipment
|
3
|
+
|
4
|
+
Charge your Camping app with some equipments to survive the cyber wildness. I
|
5
|
+
wanted to wait until I've completed the full set of tools but most of them are
|
6
|
+
already quite usable.
|
7
|
+
|
8
|
+
Before starting the adventure, choose your tools righly. Follows a list of free
|
9
|
+
tools.
|
10
|
+
|
11
|
+
Working equipment :
|
12
|
+
|
13
|
+
* Ext::AppUtil : Access to your app from a controller extension.
|
14
|
+
* Ext::ErubisView : Add Erubis template handling to your app.
|
15
|
+
* Ext::Flash : Flash data (like in rails).
|
16
|
+
* Ext::Forward : Forward a request (only for 1337 ppl).
|
17
|
+
* Ext::Patches : A set of patches for Camping to change some things.
|
18
|
+
* Ext::Sendfile : Provides `sendfile`. Uses sendfile with mongrel if available.
|
19
|
+
* Ext::TemplateView : Extension that changes camping to allow easy adding of other templating languages.
|
20
|
+
* Ext::UseHelper : Tell your template what scripts your view is using.
|
21
|
+
* Ext::XmlView : Basic Xml builder. Ripped from some _why app. Ugly yet.
|
22
|
+
|
23
|
+
|
24
|
+
Not working equipment (TODO) :
|
25
|
+
|
26
|
+
* Ext::BasicAuth : Handles HttpBasic authentication.
|
27
|
+
* Ext::Security : Generic handle for authentication and authorization.
|
28
|
+
* Ext::JsHelpers : Adds javascript helpers.
|
29
|
+
* Ext::Og : Og utilities to integrate in Camping better.
|
30
|
+
* Ext::OgScaffold : Scaffolding.
|
31
|
+
* Ext::OgSession : Session handling.
|
32
|
+
* Ext::Ressource : Rest Controller like ActiveRessource.
|
33
|
+
|
34
|
+
== Features
|
35
|
+
|
36
|
+
* The above equipments.
|
37
|
+
* Dependencies are automatically resolved.
|
38
|
+
* Equipment itself provides a cool extension mechanism.
|
39
|
+
|
40
|
+
== Usage
|
41
|
+
|
42
|
+
Include an equipment in your app's module to instantly get the features that
|
43
|
+
it describes. Modules and classes below are automatically included because of
|
44
|
+
Equipment#included(app) which is defined in each equipment by extending the
|
45
|
+
Equipment module.
|
46
|
+
|
47
|
+
example :
|
48
|
+
|
49
|
+
Camping.goes :YourApp
|
50
|
+
|
51
|
+
Ext::Mount.equip(YourApp)
|
52
|
+
|
53
|
+
module YourApp::Controllers
|
54
|
+
# ::mount is now available here
|
55
|
+
mount '/somepath', :name=>:ControllerName, :url=>'/here'
|
56
|
+
end
|
57
|
+
|
58
|
+
see in the examples for more details.
|
59
|
+
|
60
|
+
== License
|
61
|
+
|
62
|
+
GPL. not sure yet.
|
63
|
+
|
64
|
+
== Author(s)
|
65
|
+
|
66
|
+
* Jonas Pfenniger <zimba.tm@gmail.com>
|
67
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'camping'
|
2
|
+
require 'ext/basic_auth'
|
3
|
+
|
4
|
+
$DBG = true
|
5
|
+
|
6
|
+
Camping.goes :BasicAuthTest
|
7
|
+
|
8
|
+
module BasicAuthTest
|
9
|
+
Ext::BasicAuth.equip(self)
|
10
|
+
|
11
|
+
module Base
|
12
|
+
def authenticate
|
13
|
+
@user, @pass = super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Controllers
|
18
|
+
# Allow not authenticated users
|
19
|
+
class Index < R '/'
|
20
|
+
def get; render :index ; end
|
21
|
+
end
|
22
|
+
|
23
|
+
class AskAuth < R '/ask_auth'
|
24
|
+
|
25
|
+
def authorize(user, pass, force=true)
|
26
|
+
puts "Authorize called"
|
27
|
+
return false
|
28
|
+
(user == pass and not user.empty?) || super
|
29
|
+
end
|
30
|
+
|
31
|
+
def get; render :ask_auth ; end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module Views
|
36
|
+
def layout
|
37
|
+
html do
|
38
|
+
head { title "BasicAuth test" }
|
39
|
+
body do
|
40
|
+
pre 'user : ' + @user.inspect
|
41
|
+
pre 'pass : ' + @pass.inspect
|
42
|
+
div { yield }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def index
|
48
|
+
h1 "Index"
|
49
|
+
p 'User must be equal to the password.'
|
50
|
+
a "AskAuth", :href=>R(AskAuth)
|
51
|
+
end
|
52
|
+
|
53
|
+
def ask_auth
|
54
|
+
h2 "You're authenticated now."
|
55
|
+
a "Index", :href=>R(Index)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'camping'
|
2
|
+
require 'ext/eruby_view'
|
3
|
+
|
4
|
+
$DBG = true
|
5
|
+
|
6
|
+
Camping.goes :ErubyTest
|
7
|
+
|
8
|
+
|
9
|
+
module ErubyTest
|
10
|
+
Ext::ErubyView.equip(self)
|
11
|
+
|
12
|
+
Views.template_root = File.dirname(__FILE__)
|
13
|
+
|
14
|
+
module Controllers
|
15
|
+
class Index < R '/'
|
16
|
+
def get
|
17
|
+
@somevar = 'var var'
|
18
|
+
render :index
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Views
|
24
|
+
def layout
|
25
|
+
html do
|
26
|
+
head { title "Erubis test" }
|
27
|
+
body { yield }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def index
|
32
|
+
h1 "No template"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'camping'
|
2
|
+
require 'ext/flash'
|
3
|
+
|
4
|
+
$DBG = true
|
5
|
+
|
6
|
+
Camping.goes :FlashTest
|
7
|
+
|
8
|
+
|
9
|
+
module FlashTest
|
10
|
+
Ext::Flash.equip(self)
|
11
|
+
|
12
|
+
module Controllers
|
13
|
+
class Index < R '/'
|
14
|
+
def get; render :index ; end
|
15
|
+
end
|
16
|
+
|
17
|
+
class SomeError
|
18
|
+
def get;
|
19
|
+
1 / 0
|
20
|
+
rescue => ex
|
21
|
+
flash.error = ex.message
|
22
|
+
redirect R(Index)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module Views
|
28
|
+
def layout
|
29
|
+
html do
|
30
|
+
head do
|
31
|
+
title "Flash test"
|
32
|
+
end
|
33
|
+
body do
|
34
|
+
pre 'Cookies: ' + @cookies.inspect
|
35
|
+
p "Error : #{flash.error}" if flash.error
|
36
|
+
self << yield
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def index
|
42
|
+
h1 "Index"
|
43
|
+
a "SomeError", :href=>R(SomeError)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/examples/index.erb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'camping'
|
2
|
+
require 'ext/mount'
|
3
|
+
|
4
|
+
$DBG = true
|
5
|
+
|
6
|
+
Camping.goes :MountTest
|
7
|
+
|
8
|
+
|
9
|
+
module MountTest
|
10
|
+
Ext::Mount.equip(self)
|
11
|
+
|
12
|
+
module Controllers
|
13
|
+
mount File.dirname(File.expand_path(__FILE__)), :name=>:Dir, :url=>'/dir'
|
14
|
+
|
15
|
+
class Index < R '/'
|
16
|
+
def get; render :index ; end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Views
|
21
|
+
def layout
|
22
|
+
html do
|
23
|
+
head { title "Mount test" }
|
24
|
+
body { yield }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def index
|
29
|
+
h1 "Index"
|
30
|
+
a "DirListing", :href=>"/dir" #,:href=>R(Example)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
data/examples/ogtest.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'camping'
|
2
|
+
require 'ext/og_scaffold'
|
3
|
+
|
4
|
+
$DBG = true
|
5
|
+
|
6
|
+
Camping.goes :OgTest
|
7
|
+
|
8
|
+
module OgTest
|
9
|
+
Ext::OgScaffold.equip(self)
|
10
|
+
|
11
|
+
module Models
|
12
|
+
self.og = {:store => :mysql, :name=>'og_test', :user=>'root'}
|
13
|
+
|
14
|
+
class User
|
15
|
+
attr_accessor :login, String
|
16
|
+
attr_accessor :password, String
|
17
|
+
belongs_to Group
|
18
|
+
end
|
19
|
+
|
20
|
+
class Group
|
21
|
+
attr_accessor :name, String
|
22
|
+
has_many User
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Controllers
|
27
|
+
class Index < R '/'
|
28
|
+
def get
|
29
|
+
render :index
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Views
|
35
|
+
def index
|
36
|
+
h1 "Index"
|
37
|
+
p "Nothing special here"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'camping'
|
2
|
+
require 'ext/patches'
|
3
|
+
|
4
|
+
$DBG = true
|
5
|
+
|
6
|
+
Camping.goes :PatchesTest
|
7
|
+
|
8
|
+
|
9
|
+
module PatchesTest
|
10
|
+
Ext::Patches.equip(self)
|
11
|
+
|
12
|
+
module Controllers
|
13
|
+
class Index < R '/'
|
14
|
+
def get
|
15
|
+
render :index
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ZeroDiv
|
20
|
+
def get
|
21
|
+
1 / 0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Views
|
27
|
+
def layout
|
28
|
+
html do
|
29
|
+
head { title "Patches test" }
|
30
|
+
body { yield }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def index
|
35
|
+
h1 "Hello"
|
36
|
+
a "ZeroDiv", :href => R(ZeroDiv)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'camping'
|
2
|
+
require 'ext/sendfile'
|
3
|
+
|
4
|
+
$DBG = true
|
5
|
+
|
6
|
+
Camping.goes(:SendfileTest)
|
7
|
+
|
8
|
+
Ext::Sendfile.equip(SendfileTest)
|
9
|
+
|
10
|
+
module SendfileTest
|
11
|
+
|
12
|
+
module Controllers
|
13
|
+
class Index < R '/'
|
14
|
+
def get; render :index ; end
|
15
|
+
end
|
16
|
+
|
17
|
+
class GetSelf
|
18
|
+
def get; sendfile __FILE__ end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module Views
|
23
|
+
def index
|
24
|
+
h1 "Index"
|
25
|
+
a "Get self", :href=>R(GetSelf)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
data/lib/equipment.rb
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
# Equipment is a set of tools for Camping.
|
2
|
+
#
|
3
|
+
# See the README for more informations.
|
4
|
+
|
5
|
+
require 'camping'
|
6
|
+
|
7
|
+
=begin # doesn't work
|
8
|
+
class << Camping
|
9
|
+
def goes(m)
|
10
|
+
p super(m)
|
11
|
+
# app = const_get(m)
|
12
|
+
# app.extend CampingExt
|
13
|
+
# app
|
14
|
+
end
|
15
|
+
end
|
16
|
+
=end
|
17
|
+
|
18
|
+
# This module extends every app that uses equipments. It provides some
|
19
|
+
# useful methods.
|
20
|
+
module CampingExt
|
21
|
+
# List of extensions already in the application
|
22
|
+
def exts; @exts ||= [] end
|
23
|
+
|
24
|
+
# Shortcut method to add an equipment to the app.
|
25
|
+
#
|
26
|
+
# You can use YourApp.equip(Extension) instead of
|
27
|
+
# Extension.equip(YourApp) once this extension is
|
28
|
+
# installed.
|
29
|
+
#
|
30
|
+
def equip(*exts)
|
31
|
+
exts.each do |ext|
|
32
|
+
ext.equip(self)
|
33
|
+
end
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
# This will allow you to chain create methods.
|
38
|
+
#
|
39
|
+
# == Examplanation
|
40
|
+
#
|
41
|
+
# When calling YourApp.create, the call order is :
|
42
|
+
# * YourApp.create
|
43
|
+
# * Last extended module.create
|
44
|
+
# * Second last extended module.create
|
45
|
+
# * ...
|
46
|
+
# * First extended module.create
|
47
|
+
#
|
48
|
+
# By extending this app first, it will set a blank create method that
|
49
|
+
# will ensure that you don't get a NoMethodError when calling `super`
|
50
|
+
#
|
51
|
+
def create; end
|
52
|
+
|
53
|
+
# Same as for #create.
|
54
|
+
#
|
55
|
+
# This method is intended to be used by launchers that support dynamically
|
56
|
+
# installing and removing applications.
|
57
|
+
#
|
58
|
+
def install; end
|
59
|
+
|
60
|
+
# See #install.
|
61
|
+
def uninstall; end
|
62
|
+
end
|
63
|
+
|
64
|
+
module Equipment
|
65
|
+
|
66
|
+
# Utility for equipments. Automatically sets a set of rule for importing
|
67
|
+
# methods, classes, class methods in your application for your extension.
|
68
|
+
#
|
69
|
+
# == Example
|
70
|
+
#
|
71
|
+
# module MyUtil
|
72
|
+
# extend Equipment
|
73
|
+
# module ViewsClassMethod; end #=> YourApp::Views's class methods
|
74
|
+
# module Controllers; class X; end; end #=> New X controller
|
75
|
+
# module Helpers; def somemethod; end; end #=> New somemethoer
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# Camping.goes :YourApp
|
79
|
+
#
|
80
|
+
#
|
81
|
+
# module YourApp
|
82
|
+
# MyUtil.equip(self)
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# # or
|
86
|
+
#
|
87
|
+
# YourApp.extend CampingExt
|
88
|
+
# YourApp.equip(MyUtil)
|
89
|
+
#
|
90
|
+
def equip(app)
|
91
|
+
raise "Only for Camping apps" unless app.respond_to? :goes
|
92
|
+
app.extend CampingExt
|
93
|
+
|
94
|
+
# Only equip once
|
95
|
+
return false if app.exts.include?(self)
|
96
|
+
app.exts << self
|
97
|
+
|
98
|
+
# dependencies
|
99
|
+
deps.each { |ext| ext.equip(app) }
|
100
|
+
|
101
|
+
puts "** equipped #{self} in #{app}" if $DBG
|
102
|
+
|
103
|
+
app_mods = app.constants.sort.select do |name|
|
104
|
+
app.const_get(name).kind_of?(Module)
|
105
|
+
end
|
106
|
+
|
107
|
+
puts "App Mods : #{app_mods.inspect}" if $DBG
|
108
|
+
puts "Ext Mods : #{constants.inspect}" if $DBG
|
109
|
+
|
110
|
+
app_mods.each do |name|
|
111
|
+
app_mod = app.const_get(name)
|
112
|
+
if const_defined?(name) and mod = const_get(name) and
|
113
|
+
not mod.kind_of?(Class) and mod != app_mod
|
114
|
+
if mod.public_instance_methods.size > 0 or
|
115
|
+
mod.protected_instance_methods.size > 0 or
|
116
|
+
mod.private_instance_methods.size > 0
|
117
|
+
app_mod.send :include, mod
|
118
|
+
puts "Included : #{mod} -> #{app_mod}" if $DBG
|
119
|
+
# Exceptions until include_deep is working
|
120
|
+
case name
|
121
|
+
when "Helpers"
|
122
|
+
app::Base.send :include, mod
|
123
|
+
puts "Included : #{mod} -> #{app::Base}" if $DBG
|
124
|
+
app::Mab.send :include, mod
|
125
|
+
puts "Included : #{mod} -> #{app::Mab}" if $DBG
|
126
|
+
if app.const_defined? :V
|
127
|
+
app::V.send :include, mod
|
128
|
+
puts "Included : #{mod} -> #{app::V}" if $DBG
|
129
|
+
end
|
130
|
+
when "Views"
|
131
|
+
app::Mab.send :include, mod
|
132
|
+
puts "Included : #{mod} -> #{app::Mab}" if $DBG
|
133
|
+
end
|
134
|
+
end
|
135
|
+
if mod.constants.size > 0
|
136
|
+
mod.transfer_classes_to(app_mod, :force)
|
137
|
+
puts "Cls trans : #{mod} -> #{app_mod}" if $DBG
|
138
|
+
end
|
139
|
+
end
|
140
|
+
if const_defined?("#{name}ClassMethods")
|
141
|
+
mod_ext = const_get("#{name}ClassMethods")
|
142
|
+
app_mod.extend(mod_ext)
|
143
|
+
puts "Extended : #{mod_ext} -> #{app_mod}" if $DBG
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# An array of equipment modules on which that equipment depends on for
|
149
|
+
# working. Works with #included.
|
150
|
+
def deps
|
151
|
+
@__deps ||= []
|
152
|
+
end
|
153
|
+
|
154
|
+
# Asynchronous dependencies for later inclusion in a camping app. Fills
|
155
|
+
# #dependencies for #included.
|
156
|
+
def depends_on(mod); deps << mod; end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
class Module
|
161
|
+
|
162
|
+
# Utility method to transfer all classes of a module into another. It is
|
163
|
+
# useful when you write Camping extensions. cf. other equipments.
|
164
|
+
#
|
165
|
+
# I'm using this to override ServerError and NotFound controllers.
|
166
|
+
def transfer_classes_to(dest, force=false)
|
167
|
+
constants.each do |str|
|
168
|
+
k = const_get(str)
|
169
|
+
if k.kind_of? Class
|
170
|
+
dest.send :remove_const, str if force and dest.const_defined? str
|
171
|
+
dest.const_set str, k.dup unless dest.const_defined? str
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
=begin
|
179
|
+
class Object
|
180
|
+
|
181
|
+
# Sets all instance variables of an object to another
|
182
|
+
#
|
183
|
+
# if force is set to true, existing instance variables will be overwritten
|
184
|
+
def instance_variables_send(obj, force=false)
|
185
|
+
instance_variables.each do |v|
|
186
|
+
if force or not obj.instance_variables.include? v
|
187
|
+
obj.instance_variable_set(v, instance_variable_get(v))
|
188
|
+
end
|
189
|
+
end
|
190
|
+
obj
|
191
|
+
end
|
192
|
+
alias :ivs_send :instance_variables_send
|
193
|
+
end
|
194
|
+
=end
|
195
|
+
|