knjrbfw 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/knjrbfw.gemspec +29 -8
- data/lib/knj/arrayext.rb +206 -153
- data/lib/knj/autoload/backups/ping.rb +2 -2
- data/lib/knj/autoload/erubis.rb +3 -3
- data/lib/knj/autoload/facets_dictionary.rb +2 -2
- data/lib/knj/autoload/gettext.rb +3 -3
- data/lib/knj/autoload/gtk2.rb +1 -1
- data/lib/knj/autoload/json.rb +14 -0
- data/lib/knj/autoload/magick.rb +3 -3
- data/lib/knj/autoload/mysql.rb +3 -3
- data/lib/knj/autoload/parsedate.rb +1 -1
- data/lib/knj/autoload/ping.rb +2 -2
- data/lib/knj/autoload/rexml.rb +5 -5
- data/lib/knj/autoload/soap.rb +1 -1
- data/lib/knj/autoload/sqlite3.rb +3 -3
- data/lib/knj/autoload/tmail.rb +3 -3
- data/lib/knj/autoload/xmlsimple.rb +3 -3
- data/lib/knj/autoload/zip.rb +3 -3
- data/lib/knj/autoload.rb +87 -81
- data/lib/knj/cmd_gen.rb +19 -19
- data/lib/knj/cmd_parser.rb +59 -0
- data/lib/knj/compiler.rb +34 -34
- data/lib/knj/cpufreq.rb +37 -37
- data/lib/knj/csv.rb +20 -0
- data/lib/knj/datarow.rb +406 -239
- data/lib/knj/datarow_custom.rb +124 -0
- data/lib/knj/datestamp.rb +89 -89
- data/lib/knj/datet.rb +550 -454
- data/lib/knj/db.rb +1 -0
- data/lib/knj/degulesider.rb +42 -44
- data/lib/knj/erb/erb.rb +5 -5
- data/lib/knj/erb/erb_cache_clean.rb +10 -10
- data/lib/knj/erb/erb_fcgi.rb +32 -32
- data/lib/knj/erb/erb_fcgi_1.9.rb +32 -32
- data/lib/knj/erb/erb_fcgi_jruby.rb +2 -2
- data/lib/knj/erb/erb_jruby.rb +5 -5
- data/lib/knj/erb/include.rb +243 -243
- data/lib/knj/errors.rb +19 -18
- data/lib/knj/eruby.rb +12 -10
- data/lib/knj/event_filemod.rb +31 -31
- data/lib/knj/event_handler.rb +73 -67
- data/lib/knj/exchangerates.rb +37 -37
- data/lib/knj/facebook_connect.rb +95 -18
- data/lib/knj/filesystem.rb +6 -6
- data/lib/knj/fs/drivers/filesystem.rb +12 -12
- data/lib/knj/fs/drivers/ftp.rb +31 -31
- data/lib/knj/fs/drivers/ssh.rb +26 -26
- data/lib/knj/fs/fs.rb +31 -31
- data/lib/knj/gettext_fallback.rb +15 -15
- data/lib/knj/gettext_threadded.rb +75 -75
- data/lib/knj/google_sitemap.rb +53 -53
- data/lib/knj/gtk2.rb +272 -272
- data/lib/knj/gtk2_cb.rb +80 -80
- data/lib/knj/gtk2_menu.rb +55 -55
- data/lib/knj/gtk2_statuswindow.rb +62 -62
- data/lib/knj/gtk2_tv.rb +58 -58
- data/lib/knj/hash_methods.rb +27 -36
- data/lib/knj/http.rb +189 -167
- data/lib/knj/http2.rb +259 -53
- data/lib/knj/image.rb +2 -2
- data/lib/knj/includes/appserver_cli.rb +18 -18
- data/lib/knj/includes/require_info.rb +15 -0
- data/lib/knj/ip2location.rb +20 -20
- data/lib/knj/ironruby-gtk2/button.rb +14 -14
- data/lib/knj/ironruby-gtk2/dialog.rb +42 -42
- data/lib/knj/ironruby-gtk2/entry.rb +4 -4
- data/lib/knj/ironruby-gtk2/gdk_event.rb +1 -1
- data/lib/knj/ironruby-gtk2/gdk_eventbutton.rb +11 -11
- data/lib/knj/ironruby-gtk2/gdk_pixbuf.rb +9 -9
- data/lib/knj/ironruby-gtk2/gladexml.rb +102 -102
- data/lib/knj/ironruby-gtk2/glib.rb +13 -13
- data/lib/knj/ironruby-gtk2/gtk2.rb +121 -121
- data/lib/knj/ironruby-gtk2/gtk_builder.rb +29 -29
- data/lib/knj/ironruby-gtk2/gtk_cellrenderertext.rb +3 -3
- data/lib/knj/ironruby-gtk2/gtk_combobox.rb +17 -17
- data/lib/knj/ironruby-gtk2/gtk_filechooserbutton.rb +3 -3
- data/lib/knj/ironruby-gtk2/gtk_liststore.rb +16 -16
- data/lib/knj/ironruby-gtk2/gtk_menu.rb +3 -3
- data/lib/knj/ironruby-gtk2/gtk_menuitem.rb +2 -2
- data/lib/knj/ironruby-gtk2/gtk_statusicon.rb +3 -3
- data/lib/knj/ironruby-gtk2/gtk_treeiter.rb +22 -22
- data/lib/knj/ironruby-gtk2/gtk_treeselection.rb +11 -11
- data/lib/knj/ironruby-gtk2/gtk_treeview.rb +17 -17
- data/lib/knj/ironruby-gtk2/gtk_treeviewcolumn.rb +30 -30
- data/lib/knj/ironruby-gtk2/iconsize.rb +1 -1
- data/lib/knj/ironruby-gtk2/image.rb +13 -13
- data/lib/knj/ironruby-gtk2/label.rb +17 -17
- data/lib/knj/ironruby-gtk2/stock.rb +2 -2
- data/lib/knj/ironruby-gtk2/tests/test_2.rb +14 -14
- data/lib/knj/ironruby-gtk2/tests/test_ironruby_window.rb +37 -37
- data/lib/knj/ironruby-gtk2/vbox.rb +3 -3
- data/lib/knj/ironruby-gtk2/window.rb +18 -18
- data/lib/knj/jruby-gtk2/builder/test_builder.rb +11 -11
- data/lib/knj/jruby-gtk2/builder.rb +25 -25
- data/lib/knj/jruby-gtk2/cellrenderertext.rb +10 -10
- data/lib/knj/jruby-gtk2/checkbutton.rb +1 -1
- data/lib/knj/jruby-gtk2/combobox.rb +27 -27
- data/lib/knj/jruby-gtk2/dialog.rb +40 -40
- data/lib/knj/jruby-gtk2/eventbutton.rb +19 -19
- data/lib/knj/jruby-gtk2/gladexml.rb +97 -97
- data/lib/knj/jruby-gtk2/gtk2.rb +203 -203
- data/lib/knj/jruby-gtk2/hbox.rb +8 -8
- data/lib/knj/jruby-gtk2/iconsize.rb +3 -3
- data/lib/knj/jruby-gtk2/image.rb +8 -8
- data/lib/knj/jruby-gtk2/liststore.rb +54 -54
- data/lib/knj/jruby-gtk2/menu.rb +35 -35
- data/lib/knj/jruby-gtk2/progressbar.rb +10 -10
- data/lib/knj/jruby-gtk2/statusicon.rb +3 -3
- data/lib/knj/jruby-gtk2/stock.rb +6 -6
- data/lib/knj/jruby-gtk2/tests/test_glade_window.rb +36 -36
- data/lib/knj/jruby-gtk2/tests/test_normal_window.rb +3 -3
- data/lib/knj/jruby-gtk2/tests/test_trayicon.rb +2 -2
- data/lib/knj/jruby-gtk2/treeview.rb +88 -88
- data/lib/knj/jruby-gtk2/vbox.rb +10 -10
- data/lib/knj/jruby-gtk2/window.rb +7 -7
- data/lib/knj/jruby_compiler.rb +12 -12
- data/lib/knj/knj.rb +12 -11
- data/lib/knj/knj_controller.rb +13 -8
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +499 -316
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +127 -125
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +43 -25
- data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +316 -241
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +12 -0
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +146 -146
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb +24 -24
- data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +283 -283
- data/lib/knj/knjdb/libknjdb.rb +96 -52
- data/lib/knj/knjdb/libknjdb_java_sqlite3.rb +78 -78
- data/lib/knj/knjdb/libknjdb_row.rb +147 -147
- data/lib/knj/knjdb/libknjdb_sqlite3_ironruby.rb +61 -61
- data/lib/knj/knjdb/revision.rb +262 -0
- data/lib/knj/libqt.rb +69 -69
- data/lib/knj/libqt_window.rb +8 -8
- data/lib/knj/locales.rb +62 -52
- data/lib/knj/maemo/fremantle-calendar/fremantle-calendar.rb +54 -54
- data/lib/knj/mail.rb +73 -73
- data/lib/knj/mailobj.rb +82 -80
- data/lib/knj/mount.rb +113 -113
- data/lib/knj/notify.rb +11 -11
- data/lib/knj/nvidia_settings.rb +43 -43
- data/lib/knj/objects/objects_sqlhelper.rb +474 -0
- data/lib/knj/objects.rb +569 -793
- data/lib/knj/opts.rb +38 -38
- data/lib/knj/os.rb +176 -158
- data/lib/knj/php.rb +853 -683
- data/lib/knj/php_parser/arguments.rb +3 -3
- data/lib/knj/php_parser/functions.rb +95 -95
- data/lib/knj/php_parser/php_parser.rb +16 -16
- data/lib/knj/php_parser/tests/test.rb +6 -6
- data/lib/knj/php_parser/tests/test_function_run.rb +6 -6
- data/lib/knj/power_manager.rb +29 -29
- data/lib/knj/process.rb +457 -0
- data/lib/knj/process_meta.rb +400 -0
- data/lib/knj/rand.rb +8 -8
- data/lib/knj/retry.rb +69 -69
- data/lib/knj/rhodes/delegate.rb +414 -0
- data/lib/knj/rhodes/rhodes.rb +114 -40
- data/lib/knj/rhodes/weakref.rb +80 -0
- data/lib/knj/rsvgbin.rb +18 -18
- data/lib/knj/scripts/degulesider.rb +2 -2
- data/lib/knj/scripts/filesearch.rb +35 -35
- data/lib/knj/scripts/ip2location.rb +2 -2
- data/lib/knj/scripts/keepalive.rb +2 -2
- data/lib/knj/scripts/php_to_rb_helper.rb +376 -0
- data/lib/knj/scripts/process_meta_exec.rb +104 -0
- data/lib/knj/scripts/svn_merge.rb +21 -21
- data/lib/knj/scripts/upgrade_knjrbfw_checker.rb +26 -26
- data/lib/knj/sms.rb +52 -52
- data/lib/knj/sshrobot/sshrobot.rb +90 -88
- data/lib/knj/sshrobot.rb +1 -0
- data/lib/knj/strings.rb +186 -74
- data/lib/knj/sysuser.rb +25 -25
- data/lib/knj/table_writer.rb +97 -0
- data/lib/knj/tests/compiler/compiler_test.rb +2 -2
- data/lib/knj/tests/test_degulesider.rb +1 -1
- data/lib/knj/tests/test_http2_proxy.rb +26 -0
- data/lib/knj/tests/test_mount.rb +9 -9
- data/lib/knj/tests/test_retry.rb +17 -17
- data/lib/knj/thread.rb +23 -24
- data/lib/knj/thread2.rb +45 -45
- data/lib/knj/threadhandler.rb +135 -102
- data/lib/knj/threadpool.rb +195 -145
- data/lib/knj/translations.rb +128 -119
- data/lib/knj/unix_proc.rb +80 -80
- data/lib/knj/web.rb +947 -881
- data/lib/knj/webscripts/image.rhtml +142 -67
- data/lib/knj/win.rb +2 -2
- data/lib/knj/win_registry.rb +58 -58
- data/lib/knj/win_tightvnc.rb +125 -125
- data/lib/knj/wref.rb +104 -0
- data/lib/knj/x11vnc.rb +46 -46
- data/lib/knj/youtube.rb +33 -36
- data/lib/knjrbfw.rb +1 -0
- data/spec/cmd_parser_spec.rb +25 -0
- data/spec/db_spec.rb +40 -0
- data/spec/db_spec_encoding_test_file.txt +1 -0
- data/spec/http2_spec.rb +37 -0
- data/spec/knjrbfw_spec.rb +17 -15
- data/spec/php_spec.rb +69 -0
- data/spec/process_meta_spec.rb +150 -0
- data/spec/process_spec.rb +107 -0
- data/spec/strings_spec.rb +21 -0
- data/spec/web_spec.rb +16 -0
- metadata +42 -21
- data/lib/knj/autoload/json_autoload.rb +0 -7
- data/lib/knj/autoload/twitter.rb +0 -2
- data/lib/knj/ext/webrick.rb +0 -31
- data/lib/knj/jruby-gtk2/gtk-4.0.jar +0 -0
- data/lib/knj/knjdb/mysql-connector-java-5.1.13-bin.jar +0 -0
- data/lib/knj/knjdb/sqlitejdbc-v056.jar +0 -0
@@ -0,0 +1,414 @@
|
|
1
|
+
# = delegate -- Support for the Delegation Pattern
|
2
|
+
#
|
3
|
+
# Documentation by James Edward Gray II and Gavin Sinclair
|
4
|
+
#
|
5
|
+
# == Introduction
|
6
|
+
#
|
7
|
+
# This library provides three different ways to delegate method calls to an
|
8
|
+
# object. The easiest to use is SimpleDelegator. Pass an object to the
|
9
|
+
# constructor and all methods supported by the object will be delegated. This
|
10
|
+
# object can be changed later.
|
11
|
+
#
|
12
|
+
# Going a step further, the top level DelegateClass method allows you to easily
|
13
|
+
# setup delegation through class inheritance. This is considerably more
|
14
|
+
# flexible and thus probably the most common use for this library.
|
15
|
+
#
|
16
|
+
# Finally, if you need full control over the delegation scheme, you can inherit
|
17
|
+
# from the abstract class Delegator and customize as needed. (If you find
|
18
|
+
# yourself needing this control, have a look at _forwardable_, also in the
|
19
|
+
# standard library. It may suit your needs better.)
|
20
|
+
#
|
21
|
+
# == Notes
|
22
|
+
#
|
23
|
+
# Be advised, RDoc will not detect delegated methods.
|
24
|
+
#
|
25
|
+
# <b>delegate.rb provides full-class delegation via the
|
26
|
+
# DelegateClass() method. For single-method delegation via
|
27
|
+
# def_delegator(), see forwardable.rb.</b>
|
28
|
+
#
|
29
|
+
# == Examples
|
30
|
+
#
|
31
|
+
# === SimpleDelegator
|
32
|
+
#
|
33
|
+
# Here's a simple example that takes advantage of the fact that
|
34
|
+
# SimpleDelegator's delegation object can be changed at any time.
|
35
|
+
#
|
36
|
+
# class Stats
|
37
|
+
# def initialize
|
38
|
+
# @source = SimpleDelegator.new([])
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# def stats( records )
|
42
|
+
# @source.__setobj__(records)
|
43
|
+
#
|
44
|
+
# "Elements: #{@source.size}\n" +
|
45
|
+
# " Non-Nil: #{@source.compact.size}\n" +
|
46
|
+
# " Unique: #{@source.uniq.size}\n"
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# s = Stats.new
|
51
|
+
# puts s.stats(%w{James Edward Gray II})
|
52
|
+
# puts
|
53
|
+
# puts s.stats([1, 2, 3, nil, 4, 5, 1, 2])
|
54
|
+
#
|
55
|
+
# <i>Prints:</i>
|
56
|
+
#
|
57
|
+
# Elements: 4
|
58
|
+
# Non-Nil: 4
|
59
|
+
# Unique: 4
|
60
|
+
#
|
61
|
+
# Elements: 8
|
62
|
+
# Non-Nil: 7
|
63
|
+
# Unique: 6
|
64
|
+
#
|
65
|
+
# === DelegateClass()
|
66
|
+
#
|
67
|
+
# Here's a sample of use from <i>tempfile.rb</i>.
|
68
|
+
#
|
69
|
+
# A _Tempfile_ object is really just a _File_ object with a few special rules
|
70
|
+
# about storage location and/or when the File should be deleted. That makes for
|
71
|
+
# an almost textbook perfect example of how to use delegation.
|
72
|
+
#
|
73
|
+
# class Tempfile < DelegateClass(File)
|
74
|
+
# # constant and class member data initialization...
|
75
|
+
#
|
76
|
+
# def initialize(basename, tmpdir=Dir::tmpdir)
|
77
|
+
# # build up file path/name in var tmpname...
|
78
|
+
#
|
79
|
+
# @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
|
80
|
+
#
|
81
|
+
# # ...
|
82
|
+
#
|
83
|
+
# super(@tmpfile)
|
84
|
+
#
|
85
|
+
# # below this point, all methods of File are supported...
|
86
|
+
# end
|
87
|
+
#
|
88
|
+
# # ...
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# === Delegator
|
92
|
+
#
|
93
|
+
# SimpleDelegator's implementation serves as a nice example here.
|
94
|
+
#
|
95
|
+
# class SimpleDelegator < Delegator
|
96
|
+
# def initialize(obj)
|
97
|
+
# super # pass obj to Delegator constructor, required
|
98
|
+
# @delegate_sd_obj = obj # store obj for future use
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# def __getobj__
|
102
|
+
# @delegate_sd_obj # return object we are delegating to, required
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# def __setobj__(obj)
|
106
|
+
# @delegate_sd_obj = obj # change delegation object, a feature we're providing
|
107
|
+
# end
|
108
|
+
#
|
109
|
+
# # ...
|
110
|
+
# end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Delegator is an abstract class used to build delegator pattern objects from
|
114
|
+
# subclasses. Subclasses should redefine \_\_getobj\_\_. For a concrete
|
115
|
+
# implementation, see SimpleDelegator.
|
116
|
+
#
|
117
|
+
class Delegator < BasicObject
|
118
|
+
kernel = ::Kernel.dup
|
119
|
+
kernel.class_eval do
|
120
|
+
[:to_s,:inspect,:=~,:!~,:===,:<=>,:eql?,:hash].each do |m|
|
121
|
+
undef_method m
|
122
|
+
end
|
123
|
+
end
|
124
|
+
include kernel
|
125
|
+
|
126
|
+
# :stopdoc:
|
127
|
+
def self.const_missing(n)
|
128
|
+
::Object.const_get(n)
|
129
|
+
end
|
130
|
+
# :startdoc:
|
131
|
+
|
132
|
+
#
|
133
|
+
# Pass in the _obj_ to delegate method calls to. All methods supported by
|
134
|
+
# _obj_ will be delegated to.
|
135
|
+
#
|
136
|
+
def initialize(obj)
|
137
|
+
__setobj__(obj)
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# Handles the magic of delegation through \_\_getobj\_\_.
|
142
|
+
#
|
143
|
+
def method_missing(m, *args, &block)
|
144
|
+
target = self.__getobj__
|
145
|
+
begin
|
146
|
+
target.respond_to?(m) ? target.__send__(m, *args, &block) : super(m, *args, &block)
|
147
|
+
ensure
|
148
|
+
$@.delete_if {|t| %r"\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:"o =~ t} if $@
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
#
|
153
|
+
# Checks for a method provided by this the delegate object by forwarding the
|
154
|
+
# call through \_\_getobj\_\_.
|
155
|
+
#
|
156
|
+
def respond_to_missing?(m, include_private)
|
157
|
+
r = self.__getobj__.respond_to?(m, include_private)
|
158
|
+
if r && include_private && !self.__getobj__.respond_to?(m, false)
|
159
|
+
warn "#{caller(3)[0]}: delegator does not forward private method \##{m}"
|
160
|
+
return false
|
161
|
+
end
|
162
|
+
r
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Returns the methods available to this delegate object as the union
|
167
|
+
# of this object's and \_\_getobj\_\_ methods.
|
168
|
+
#
|
169
|
+
def methods
|
170
|
+
__getobj__.methods | super
|
171
|
+
end
|
172
|
+
|
173
|
+
#
|
174
|
+
# Returns the methods available to this delegate object as the union
|
175
|
+
# of this object's and \_\_getobj\_\_ public methods.
|
176
|
+
#
|
177
|
+
def public_methods(all=true)
|
178
|
+
__getobj__.public_methods(all) | super
|
179
|
+
end
|
180
|
+
|
181
|
+
#
|
182
|
+
# Returns the methods available to this delegate object as the union
|
183
|
+
# of this object's and \_\_getobj\_\_ protected methods.
|
184
|
+
#
|
185
|
+
def protected_methods(all=true)
|
186
|
+
__getobj__.protected_methods(all) | super
|
187
|
+
end
|
188
|
+
|
189
|
+
# Note: no need to specialize private_methods, since they are not forwarded
|
190
|
+
|
191
|
+
#
|
192
|
+
# Returns true if two objects are considered of equal value.
|
193
|
+
#
|
194
|
+
def ==(obj)
|
195
|
+
return true if obj.equal?(self)
|
196
|
+
self.__getobj__ == obj
|
197
|
+
end
|
198
|
+
|
199
|
+
#
|
200
|
+
# Returns true if two objects are not considered of equal value.
|
201
|
+
#
|
202
|
+
def !=(obj)
|
203
|
+
return false if obj.equal?(self)
|
204
|
+
__getobj__ != obj
|
205
|
+
end
|
206
|
+
|
207
|
+
def !
|
208
|
+
!__getobj__
|
209
|
+
end
|
210
|
+
|
211
|
+
#
|
212
|
+
# This method must be overridden by subclasses and should return the object
|
213
|
+
# method calls are being delegated to.
|
214
|
+
#
|
215
|
+
def __getobj__
|
216
|
+
raise NotImplementedError, "need to define `__getobj__'"
|
217
|
+
end
|
218
|
+
|
219
|
+
#
|
220
|
+
# This method must be overridden by subclasses and change the object delegate
|
221
|
+
# to _obj_.
|
222
|
+
#
|
223
|
+
def __setobj__(obj)
|
224
|
+
raise NotImplementedError, "need to define `__setobj__'"
|
225
|
+
end
|
226
|
+
|
227
|
+
#
|
228
|
+
# Serialization support for the object returned by \_\_getobj\_\_.
|
229
|
+
#
|
230
|
+
def marshal_dump
|
231
|
+
ivars = instance_variables.reject {|var| /\A@delegate_/ =~ var}
|
232
|
+
[
|
233
|
+
:__v2__,
|
234
|
+
ivars, ivars.map{|var| instance_variable_get(var)},
|
235
|
+
__getobj__
|
236
|
+
]
|
237
|
+
end
|
238
|
+
|
239
|
+
#
|
240
|
+
# Reinitializes delegation from a serialized object.
|
241
|
+
#
|
242
|
+
def marshal_load(data)
|
243
|
+
version, vars, values, obj = data
|
244
|
+
if version == :__v2__
|
245
|
+
vars.each_with_index{|var, i| instance_variable_set(var, values[i])}
|
246
|
+
__setobj__(obj)
|
247
|
+
else
|
248
|
+
__setobj__(data)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def initialize_clone(obj) # :nodoc:
|
253
|
+
self.__setobj__(obj.__getobj__.clone)
|
254
|
+
end
|
255
|
+
def initialize_dup(obj) # :nodoc:
|
256
|
+
self.__setobj__(obj.__getobj__.dup)
|
257
|
+
end
|
258
|
+
private :initialize_clone, :initialize_dup
|
259
|
+
|
260
|
+
##
|
261
|
+
# :method: trust
|
262
|
+
# Trust both the object returned by \_\_getobj\_\_ and self.
|
263
|
+
#
|
264
|
+
|
265
|
+
##
|
266
|
+
# :method: untrust
|
267
|
+
# Untrust both the object returned by \_\_getobj\_\_ and self.
|
268
|
+
#
|
269
|
+
|
270
|
+
##
|
271
|
+
# :method: taint
|
272
|
+
# Taint both the object returned by \_\_getobj\_\_ and self.
|
273
|
+
#
|
274
|
+
|
275
|
+
##
|
276
|
+
# :method: untaint
|
277
|
+
# Untaint both the object returned by \_\_getobj\_\_ and self.
|
278
|
+
#
|
279
|
+
|
280
|
+
[:trust, :untrust, :taint, :untaint].each do |method|
|
281
|
+
define_method method do
|
282
|
+
__getobj__.send(method)
|
283
|
+
super()
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
#
|
288
|
+
# Freeze self and target at once.
|
289
|
+
#
|
290
|
+
def freeze
|
291
|
+
__getobj__.freeze
|
292
|
+
super
|
293
|
+
end
|
294
|
+
|
295
|
+
@delegator_api = self.public_instance_methods
|
296
|
+
def self.public_api # :nodoc:
|
297
|
+
@delegator_api
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
#
|
302
|
+
# A concrete implementation of Delegator, this class provides the means to
|
303
|
+
# delegate all supported method calls to the object passed into the constructor
|
304
|
+
# and even to change the object being delegated to at a later time with
|
305
|
+
# \_\_setobj\_\_ .
|
306
|
+
#
|
307
|
+
class SimpleDelegator<Delegator
|
308
|
+
# Returns the current object method calls are being delegated to.
|
309
|
+
def __getobj__
|
310
|
+
@delegate_sd_obj
|
311
|
+
end
|
312
|
+
|
313
|
+
#
|
314
|
+
# Changes the delegate object to _obj_.
|
315
|
+
#
|
316
|
+
# It's important to note that this does *not* cause SimpleDelegator's methods
|
317
|
+
# to change. Because of this, you probably only want to change delegation
|
318
|
+
# to objects of the same type as the original delegate.
|
319
|
+
#
|
320
|
+
# Here's an example of changing the delegation object.
|
321
|
+
#
|
322
|
+
# names = SimpleDelegator.new(%w{James Edward Gray II})
|
323
|
+
# puts names[1] # => Edward
|
324
|
+
# names.__setobj__(%w{Gavin Sinclair})
|
325
|
+
# puts names[1] # => Sinclair
|
326
|
+
#
|
327
|
+
def __setobj__(obj)
|
328
|
+
raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
|
329
|
+
@delegate_sd_obj = obj
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# :stopdoc:
|
334
|
+
def Delegator.delegating_block(mid)
|
335
|
+
lambda do |*args, &block|
|
336
|
+
target = self.__getobj__
|
337
|
+
begin
|
338
|
+
target.__send__(mid, *args, &block)
|
339
|
+
ensure
|
340
|
+
$@.delete_if {|t| /\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:/o =~ t} if $@
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
# :startdoc:
|
345
|
+
|
346
|
+
#
|
347
|
+
# The primary interface to this library. Use to setup delegation when defining
|
348
|
+
# your class.
|
349
|
+
#
|
350
|
+
# class MyClass < DelegateClass( ClassToDelegateTo ) # Step 1
|
351
|
+
# def initialize
|
352
|
+
# super(obj_of_ClassToDelegateTo) # Step 2
|
353
|
+
# end
|
354
|
+
# end
|
355
|
+
#
|
356
|
+
def DelegateClass(superclass)
|
357
|
+
klass = Class.new(Delegator)
|
358
|
+
methods = superclass.instance_methods
|
359
|
+
methods -= ::Delegator.public_api
|
360
|
+
methods -= [:to_s,:inspect,:=~,:!~,:===]
|
361
|
+
klass.module_eval do
|
362
|
+
def __getobj__ # :nodoc:
|
363
|
+
@delegate_dc_obj
|
364
|
+
end
|
365
|
+
def __setobj__(obj) # :nodoc:
|
366
|
+
raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
|
367
|
+
@delegate_dc_obj = obj
|
368
|
+
end
|
369
|
+
methods.each do |method|
|
370
|
+
define_method(method, Delegator.delegating_block(method))
|
371
|
+
end
|
372
|
+
end
|
373
|
+
klass.define_singleton_method :public_instance_methods do |all=true|
|
374
|
+
super(all) - superclass.protected_instance_methods
|
375
|
+
end
|
376
|
+
klass.define_singleton_method :protected_instance_methods do |all=true|
|
377
|
+
super(all) | superclass.protected_instance_methods
|
378
|
+
end
|
379
|
+
return klass
|
380
|
+
end
|
381
|
+
|
382
|
+
# :enddoc:
|
383
|
+
|
384
|
+
if __FILE__ == $0
|
385
|
+
class ExtArray<DelegateClass(Array)
|
386
|
+
def initialize()
|
387
|
+
super([])
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
ary = ExtArray.new
|
392
|
+
p ary.class
|
393
|
+
ary.push 25
|
394
|
+
p ary
|
395
|
+
ary.push 42
|
396
|
+
ary.each {|x| p x}
|
397
|
+
|
398
|
+
foo = Object.new
|
399
|
+
def foo.test
|
400
|
+
25
|
401
|
+
end
|
402
|
+
def foo.iter
|
403
|
+
yield self
|
404
|
+
end
|
405
|
+
def foo.error
|
406
|
+
raise 'this is OK'
|
407
|
+
end
|
408
|
+
foo2 = SimpleDelegator.new(foo)
|
409
|
+
p foo2
|
410
|
+
foo2.instance_eval{print "foo\n"}
|
411
|
+
p foo.test == foo2.test # => true
|
412
|
+
p foo2.iter{[55,true]} # => true
|
413
|
+
foo2.error # raise error!
|
414
|
+
end
|
data/lib/knj/rhodes/rhodes.rb
CHANGED
@@ -1,29 +1,44 @@
|
|
1
1
|
$knjautoload = false
|
2
2
|
|
3
3
|
class Knj::Rhodes
|
4
|
+
attr_accessor :locale
|
4
5
|
attr_reader :db, :ob, :gettext, :args
|
5
6
|
|
6
7
|
def initialize(args = {})
|
7
|
-
require "
|
8
|
-
require "
|
9
|
-
require "
|
10
|
-
require "
|
11
|
-
require "
|
12
|
-
require "
|
13
|
-
require "
|
14
|
-
require "
|
15
|
-
require "
|
16
|
-
require "
|
17
|
-
require "
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
8
|
+
require "#{$knjpath}arrayext.rb"
|
9
|
+
require "#{$knjpath}datet.rb"
|
10
|
+
require "#{$knjpath}php.rb"
|
11
|
+
require "#{$knjpath}objects.rb"
|
12
|
+
require "#{$knjpath}datarow.rb"
|
13
|
+
require "#{$knjpath}event_handler.rb"
|
14
|
+
require "#{$knjpath}hash_methods.rb"
|
15
|
+
require "#{$knjpath}errors.rb"
|
16
|
+
require "#{$knjpath}gettext_threadded.rb"
|
17
|
+
require "#{$knjpath}locales.rb"
|
18
|
+
require "#{$knjpath}web.rb"
|
19
|
+
|
20
|
+
if !Kernel.const_defined?("Mutex")
|
21
|
+
print "Mutex not defined - loading alternative.\n"
|
22
|
+
require "#{$knjpath}rhodes/mutex.rb"
|
23
|
+
end
|
24
|
+
|
25
|
+
if !Kernel.const_defined?("WeakRef")
|
26
|
+
print "WeakRef not defined - loading alternative.\n"
|
27
|
+
require "#{$knjpath}rhodes/weakref.rb"
|
28
|
+
end
|
29
|
+
|
30
|
+
require "#{$knjpath}opts.rb"
|
31
|
+
|
32
|
+
require "#{$knjpath}knjdb/libknjdb.rb"
|
33
|
+
require "#{$knjpath}knjdb/revision.rb"
|
34
|
+
require "#{$knjpath}knjdb/drivers/sqlite3/knjdb_sqlite3.rb"
|
35
|
+
require "#{$knjpath}knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb"
|
36
|
+
require "#{$knjpath}knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb"
|
37
|
+
require "#{$knjpath}knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb"
|
25
38
|
|
26
39
|
@args = args
|
40
|
+
@callbacks = {}
|
41
|
+
@callbacks_count = 0
|
27
42
|
|
28
43
|
@db = Knj::Db.new(
|
29
44
|
:type => "sqlite3",
|
@@ -47,16 +62,16 @@ class Knj::Rhodes
|
|
47
62
|
]
|
48
63
|
}
|
49
64
|
|
50
|
-
|
51
|
-
dbrev = Knjdbrevision.new
|
65
|
+
dbrev = Knj::Db::Revision.new
|
52
66
|
dbrev.init_db(schema, @db)
|
53
67
|
|
54
68
|
@ob = Knj::Objects.new(
|
55
69
|
:db => @db,
|
56
|
-
:class_path => "#{Rho::RhoApplication.get_base_app_path}app/
|
70
|
+
:class_path => "#{Rho::RhoApplication.get_base_app_path}app/models",
|
57
71
|
:require => false,
|
58
72
|
:module => @args[:module],
|
59
|
-
:datarow => true
|
73
|
+
:datarow => true,
|
74
|
+
:cache => :none
|
60
75
|
)
|
61
76
|
|
62
77
|
Knj::Opts.init(
|
@@ -66,6 +81,29 @@ class Knj::Rhodes
|
|
66
81
|
|
67
82
|
@gettext = Knj::Gettext_threadded.new
|
68
83
|
@gettext.load_dir("#{Rho::RhoApplication.get_base_app_path}app/locales")
|
84
|
+
|
85
|
+
locale = "#{System.get_property("locale")}_#{System.get_property("country")}".downcase
|
86
|
+
|
87
|
+
@args[:locale_default] = "en_GB" if !@args[:locale_default]
|
88
|
+
|
89
|
+
langs = @gettext.langs.keys
|
90
|
+
langs.each do |lang|
|
91
|
+
if locale == lang.downcase
|
92
|
+
@locale = lang
|
93
|
+
break
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if !@locale
|
98
|
+
langs.each do |lang|
|
99
|
+
if locale.slice(0..2) == lang.downcase.slice(0..2)
|
100
|
+
@locale = lang
|
101
|
+
break
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
@locale = @args[:locale_default] if !@locale
|
69
107
|
end
|
70
108
|
|
71
109
|
def inputs(*arr)
|
@@ -78,7 +116,7 @@ class Knj::Rhodes
|
|
78
116
|
|
79
117
|
if data.key?(:value) and data[:value].is_a?(Array) and data[:value][0]
|
80
118
|
value = data[:value][0][data[:value][1]]
|
81
|
-
elsif data.key?(:
|
119
|
+
elsif data.key?(:valthread_callbackue)
|
82
120
|
value = data[:value]
|
83
121
|
end
|
84
122
|
|
@@ -90,28 +128,64 @@ class Knj::Rhodes
|
|
90
128
|
if data[:type] == :textarea
|
91
129
|
css["height"] = data[:height] if data.key?(:height)
|
92
130
|
|
93
|
-
html
|
94
|
-
html
|
95
|
-
html
|
96
|
-
html
|
131
|
+
html << "<div data-role=\"fieldcontain\">"
|
132
|
+
html << "<label for=\"#{data[:name]}\">#{data[:title]}</label>"
|
133
|
+
html << "<textarea name=\"#{data[:name]}\" id=\"#{data[:name]}\"#{Knj::Web.style_html(css)}#{extra_args}>#{value}</textarea>"
|
134
|
+
html << "</div>"
|
97
135
|
else
|
98
|
-
html
|
99
|
-
html
|
100
|
-
html
|
101
|
-
html
|
136
|
+
html << "<div data-role=\"fieldcontain\">"
|
137
|
+
html << "<label for=\"#{data[:name]}\">#{data[:title]}</label>"
|
138
|
+
html << "<input type=\"#{data[:type]}\" name=\"#{data[:name]}\" id=\"#{data[:name]}\" value=\"#{value}\"#{Knj::Web.style_html(css)}#{extra_args} />"
|
139
|
+
html << "</div>"
|
102
140
|
end
|
103
141
|
end
|
104
142
|
|
105
143
|
return html
|
106
144
|
end
|
107
145
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
146
|
+
def self.html_links(args)
|
147
|
+
html_cont = "#{args[:html]}"
|
148
|
+
|
149
|
+
html_cont.scan(/(<a([^>]+)href=\"(http.+?)\")/) do |match|
|
150
|
+
html_cont = html_cont.gsub(match[0], "<a#{match[1]}href=\"javascript: knj_rhodes_html_links({url: '#{match[2]}'});\"")
|
151
|
+
end
|
152
|
+
|
153
|
+
return html_cont
|
154
|
+
end
|
155
|
+
|
156
|
+
def _(str)
|
157
|
+
return @gettext.trans(@locale, str.to_s)
|
158
|
+
end
|
159
|
+
|
160
|
+
def session_key(key)
|
161
|
+
if key == :locale
|
162
|
+
return @locale
|
163
|
+
end
|
164
|
+
|
165
|
+
raise "No such key: '#{key}'."
|
166
|
+
end
|
167
|
+
|
168
|
+
def callback(&block)
|
169
|
+
count = @callbacks_count
|
170
|
+
@callbacks_count += 1
|
171
|
+
@callbacks[count] = block
|
172
|
+
return count
|
173
|
+
end
|
174
|
+
|
175
|
+
def callbacks(key)
|
176
|
+
block = @callbacks[key.to_i]
|
177
|
+
raise "Block not found for key: '#{key}'." if !block
|
178
|
+
@callbacks.delete(key.to_i)
|
179
|
+
return block
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
#This method is used to emulate web-behavior and make Knj::Locales.number_out and friends work properly.
|
184
|
+
def _session(key)
|
185
|
+
return $rhodes.session_key(key)
|
186
|
+
end
|
187
|
+
|
188
|
+
#This method is used to make gettext work.
|
189
|
+
def _(key)
|
190
|
+
return $rhodes._(key)
|
117
191
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# Weak Reference class that does not bother GCing.
|
2
|
+
#
|
3
|
+
# Usage:
|
4
|
+
# foo = Object.new
|
5
|
+
# foo = Object.new
|
6
|
+
# p foo.to_s # original's class
|
7
|
+
# foo = WeakRef.new(foo)
|
8
|
+
# p foo.to_s # should be same class
|
9
|
+
# ObjectSpace.garbage_collect
|
10
|
+
# p foo.to_s # should raise exception (recycled)
|
11
|
+
|
12
|
+
require "#{$knjpath}rhodes/delegate"
|
13
|
+
require "thread"
|
14
|
+
|
15
|
+
class WeakRef < Delegator
|
16
|
+
|
17
|
+
class RefError < StandardError
|
18
|
+
end
|
19
|
+
|
20
|
+
@@id_map = {} # obj -> [ref,...]
|
21
|
+
@@id_rev_map = {} # ref -> obj
|
22
|
+
@@mutex = Mutex.new
|
23
|
+
@@final = lambda {|id|
|
24
|
+
@@mutex.synchronize {
|
25
|
+
rids = @@id_map[id]
|
26
|
+
if rids
|
27
|
+
for rid in rids
|
28
|
+
@@id_rev_map.delete(rid)
|
29
|
+
end
|
30
|
+
@@id_map.delete(id)
|
31
|
+
end
|
32
|
+
rid = @@id_rev_map[id]
|
33
|
+
if rid
|
34
|
+
@@id_rev_map.delete(id)
|
35
|
+
@@id_map[rid].delete(id)
|
36
|
+
@@id_map.delete(rid) if @@id_map[rid].empty?
|
37
|
+
end
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
def initialize(orig)
|
42
|
+
@__id = orig.object_id
|
43
|
+
ObjectSpace.define_finalizer orig, @@final
|
44
|
+
ObjectSpace.define_finalizer self, @@final
|
45
|
+
@@mutex.synchronize {
|
46
|
+
@@id_map[@__id] = [] unless @@id_map[@__id]
|
47
|
+
}
|
48
|
+
@@id_map[@__id].push self.object_id
|
49
|
+
@@id_rev_map[self.object_id] = @__id
|
50
|
+
super
|
51
|
+
end
|
52
|
+
|
53
|
+
def __getobj__
|
54
|
+
unless @@id_rev_map[self.object_id] == @__id
|
55
|
+
Kernel::raise RefError, "Invalid Reference - probably recycled", Kernel::caller(2)
|
56
|
+
end
|
57
|
+
begin
|
58
|
+
ObjectSpace._id2ref(@__id)
|
59
|
+
rescue RangeError
|
60
|
+
Kernel::raise RefError, "Invalid Reference - probably recycled", Kernel::caller(2)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
def __setobj__(obj)
|
64
|
+
end
|
65
|
+
|
66
|
+
def weakref_alive?
|
67
|
+
@@id_rev_map[self.object_id] == @__id
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
if __FILE__ == $0
|
72
|
+
# require 'thread'
|
73
|
+
foo = Object.new
|
74
|
+
p foo.to_s # original's class
|
75
|
+
foo = WeakRef.new(foo)
|
76
|
+
p foo.to_s # should be same class
|
77
|
+
ObjectSpace.garbage_collect
|
78
|
+
ObjectSpace.garbage_collect
|
79
|
+
p foo.to_s # should raise exception (recycled)
|
80
|
+
end
|