ruby-ext 0.2.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.
Files changed (113) hide show
  1. data/.git/COMMIT_EDITMSG +1 -0
  2. data/.git/HEAD +1 -0
  3. data/.git/config +12 -0
  4. data/.git/description +1 -0
  5. data/.git/hooks/applypatch-msg.sample +15 -0
  6. data/.git/hooks/commit-msg.sample +24 -0
  7. data/.git/hooks/post-commit.sample +8 -0
  8. data/.git/hooks/post-receive.sample +15 -0
  9. data/.git/hooks/post-update.sample +8 -0
  10. data/.git/hooks/pre-applypatch.sample +14 -0
  11. data/.git/hooks/pre-commit.sample +46 -0
  12. data/.git/hooks/pre-rebase.sample +169 -0
  13. data/.git/hooks/prepare-commit-msg.sample +36 -0
  14. data/.git/hooks/update.sample +128 -0
  15. data/.git/index +0 -0
  16. data/.git/info/exclude +6 -0
  17. data/.git/logs/HEAD +6 -0
  18. data/.git/logs/refs/heads/master +6 -0
  19. data/.git/logs/refs/remotes/origin/master +5 -0
  20. data/.git/objects/01/a6ccb4f4fb0c6cfdf9ec1bb23779721cf503e9 +5 -0
  21. data/.git/objects/05/18bc8be5c58a5bd9d7fc82c75c87478aa361e9 +5 -0
  22. data/.git/objects/05/b76a8d022e0e0fbca5b69b9f7b4d2a132fcc89 +0 -0
  23. data/.git/objects/06/864a068d188ab7ae17e39d58d6c25dc49a8ff3 +2 -0
  24. data/.git/objects/0e/13cf36bc744c90f576c0a31c3f76dcf1fd2485 +0 -0
  25. data/.git/objects/0f/add343d54917efbd138ee2d7c092a52b12ebd5 +0 -0
  26. data/.git/objects/10/53306d48d434b477991f5fb64a6d8d3aca84a0 +0 -0
  27. data/.git/objects/17/70296a7ba0a9aaadd3e857ae34d92d2e13e935 +0 -0
  28. data/.git/objects/20/c2ee1bb9f6749181e464a4ce444092fc1a1ecb +0 -0
  29. data/.git/objects/26/4d70a16bbad0c5b3b16fb7a92bcc6178f2cca2 +2 -0
  30. data/.git/objects/27/eb5694d78540b1a489a1aff5415d4713d5fca9 +0 -0
  31. data/.git/objects/29/88f150ee1623b97d234b2742b30caad382775b +0 -0
  32. data/.git/objects/29/8cb590f97362cc7a326815dac3289a88b69153 +0 -0
  33. data/.git/objects/2b/edc3eb69408a817194c28d14fb2dbfed5a21c0 +2 -0
  34. data/.git/objects/2e/3e3fc8e46949a9b944da3c36207c444aa2c9b7 +0 -0
  35. data/.git/objects/2f/74073c8d1580f5a8fc59389b4c1b6d89e4d85f +0 -0
  36. data/.git/objects/34/a418e8c4b43510124491ff3be262edd8008043 +3 -0
  37. data/.git/objects/38/91f271b22f2a1caee6910a34139076e27ade00 +0 -0
  38. data/.git/objects/38/bf6dbb2520b448e08ac9cb353523bbc72118db +0 -0
  39. data/.git/objects/44/73d59f32a2806eca098ba6bf10cdc2e6453542 +0 -0
  40. data/.git/objects/44/e92f51b4c9a44497c7f170598fae64564052eb +0 -0
  41. data/.git/objects/4b/2ac3de91e560277749f749ed47230ef080d36c +0 -0
  42. data/.git/objects/54/4fb213faf0c1b4cc459ada84120823d204ae3a +4 -0
  43. data/.git/objects/55/a433dd00ba298006a2fc028964eb0cde7c2e5b +0 -0
  44. data/.git/objects/55/f338afb8c82f8cad38b28d0e8cf887f9bda1ce +1 -0
  45. data/.git/objects/57/cf2479bb9c6e31118c42c5cceaffada1862c72 +0 -0
  46. data/.git/objects/59/60bdbdc3be504b89371c2b4b09d22754251260 +0 -0
  47. data/.git/objects/59/653cefe5b174e4a7002100f024448cdb337373 +0 -0
  48. data/.git/objects/5c/28c251bb201232470340d73ed4cc4926cd241d +0 -0
  49. data/.git/objects/5c/536c5d712f7cf34e21be5526aa3e826888810f +0 -0
  50. data/.git/objects/5d/37379f1b929c7b82f96382fc256895a50e97fd +0 -0
  51. data/.git/objects/60/a681e873ca0ae0b7da3f37dbc5701f6e42b970 +1 -0
  52. data/.git/objects/61/d4509b8fc63e53b8e5d417ace33919e8a7a8f2 +0 -0
  53. data/.git/objects/6b/dcac704e4f8abe1928e8f3f5d9b7e17e4992de +0 -0
  54. data/.git/objects/6c/18afba63861887fb7ac53fee1b24c181b2a8e4 +0 -0
  55. data/.git/objects/70/222d828221b1884b6b8ce124b7f22eea5d420d +0 -0
  56. data/.git/objects/74/bf8f37d70d9818474e1fb5081f04c496741a28 +0 -0
  57. data/.git/objects/77/141a7a91a61baff283e5f16e55a720d0bc65e0 +2 -0
  58. data/.git/objects/81/6bb8c35fe2169fa9ecbcd40941c440e5d032e1 +2 -0
  59. data/.git/objects/81/a5373f6837b02ace55c07cebf4a60fb6d4b084 +0 -0
  60. data/.git/objects/82/8cab0a228a826cb346b6cf4ffffac84c674e4b +3 -0
  61. data/.git/objects/84/2a9747ce87d8b90ee360f7252b557ff8e19352 +0 -0
  62. data/.git/objects/90/eea923ef08bb39013e7cd5be777b7539733638 +0 -0
  63. data/.git/objects/93/276f74ef0e157c5f81eeec7844f30d4eceda7a +0 -0
  64. data/.git/objects/9e/a37d9fc7e1ad1504b50da2a1ec639c523fb8b7 +2 -0
  65. data/.git/objects/ab/daaab37771475482389bdfcb2021b1651ba399 +0 -0
  66. data/.git/objects/ad/e1a70e7cf984a2f518d19ef625362d78a5fbd0 +3 -0
  67. data/.git/objects/b6/17a8cc2ae7f6ea496051db493aa56edc178073 +0 -0
  68. data/.git/objects/b6/863b5d4c0a4d87b81a9bbc29e786fcf7ef0df2 +0 -0
  69. data/.git/objects/bc/ee5c51061bdb9ab5a5aea4f00245a8ab3689b2 +0 -0
  70. data/.git/objects/c3/faad9ba42388a50a57acf9df88f6d2a64a4122 +1 -0
  71. data/.git/objects/d4/8b935ca7e38d2434ceb1711544293f4baf8203 +0 -0
  72. data/.git/objects/dd/e851a435431f0c03b12f7a9ca6e5dd5ce80617 +0 -0
  73. data/.git/objects/e0/c54997bfab8a0bf135d0de79ddee431b9112ad +0 -0
  74. data/.git/objects/e9/d385c1913656b7ce15a1ac1424361d2e065a6c +0 -0
  75. data/.git/objects/f0/c37cf78e53e6f859111f35d9dbf52cbfbc633d +0 -0
  76. data/.git/objects/f1/2346269ed5287267f0271f57546291c013b318 +0 -0
  77. data/.git/objects/f3/655e33b96e5b8b25990a2ae88fcdfed415074b +0 -0
  78. data/.git/objects/f7/c0fa5621b81aca548c738c08907055696e1956 +0 -0
  79. data/.git/objects/f8/c960b12cbddb90f18123673e6778efdc822058 +2 -0
  80. data/.git/objects/fb/85b5793dcebae826b04cd8c37406504540d8a4 +2 -0
  81. data/.git/objects/fd/d3ef7ec06e804f3688491e21caaa4d89796b16 +0 -0
  82. data/.git/objects/pack/pack-304aec40b1be62a8e3c105c6423354d9e62bd089.idx +0 -0
  83. data/.git/objects/pack/pack-304aec40b1be62a8e3c105c6423354d9e62bd089.pack +0 -0
  84. data/.git/packed-refs +2 -0
  85. data/.git/refs/heads/master +1 -0
  86. data/.git/refs/remotes/origin/HEAD +1 -0
  87. data/.git/refs/remotes/origin/master +1 -0
  88. data/.gitignore +5 -0
  89. data/README.rdoc +3 -0
  90. data/Rakefile +64 -0
  91. data/lib/ruby_ext/declarative_cache.rb +167 -0
  92. data/lib/ruby_ext/file.rb +23 -0
  93. data/lib/ruby_ext/kernel.rb +21 -0
  94. data/lib/ruby_ext/module.rb +84 -0
  95. data/lib/ruby_ext/not_defined.rb +2 -0
  96. data/lib/ruby_ext/object.rb +7 -0
  97. data/lib/ruby_ext/open_constructor.rb +51 -0
  98. data/lib/ruby_ext/prepare_arguments.rb +105 -0
  99. data/lib/ruby_ext/should.rb +150 -0
  100. data/lib/ruby_ext/string.rb +21 -0
  101. data/lib/ruby_ext/symbol.rb +21 -0
  102. data/lib/ruby_ext/synchronizer.rb +31 -0
  103. data/lib/ruby_ext.rb +17 -0
  104. data/spec/assert_spec.rb +27 -0
  105. data/spec/declarative_cache_spec.rb +97 -0
  106. data/spec/kernel_spec.rb +16 -0
  107. data/spec/module_spec.rb +127 -0
  108. data/spec/open_constructor_spec.rb +39 -0
  109. data/spec/prepare_arguments_spec.rb +50 -0
  110. data/spec/spec.opts +3 -0
  111. data/spec/spec_require.rb +10 -0
  112. data/spec/synchronizer_spec.rb +69 -0
  113. metadata +166 -0
@@ -0,0 +1,2 @@
1
+ x��N�0ƽݞ�d^p!�-�I���;c�n;d5�Ŷ� ��v�}]�2�}���k!uYv�^|k�A�-��8���9��DF��o�|uw����&��NS���a�Kel*E15M��q�v���h%>�$q��U#H^�\UhK#
2
+ ���ۘ@��(�ޝF����mY�FQz��ѐ{P��;ghT^������fΗ���p
@@ -0,0 +1,3 @@
1
+ x]QmK�0�k�+�Mt�Va� *�����7�B��X Mf������-�hz�{��N����h����a�pVG�9/\^��O�枲_�9�V�2G�����Ж3�:�!L0�]Xw8c9� ���n�B�ĺ0C��;XZY��1i�� ��}|��듐��������eos� !��P�e��xI��I�eʕ6�o(>�4�t�i�� 8�%��_�к7l(TP^/"��=�N�J�j�] ak���z�
2
+ EW�9ڼ����K-������"Ew��%$uЫ�)�硐�$Tg hf��!J�Pt�����L9cP�jY,��,�S������;v�]�FLZ��5/��Z�N�0�=��[��W�:��𧋞
3
+ ��
@@ -0,0 +1,2 @@
1
+ x��A
2
+ �0@Q�9E���$q:E�(�d�BkK������=�e��G�(t蛙o�Fk� cH-s��EUSe�2�[u�g�![-�2IV�%��Sˡ�f�����~_6���G�{��4-E���@�(Fa��������yu.�<�
@@ -0,0 +1,3 @@
1
+ x�MN�0��&��E�n²j��h%$V���I���k���wg�$��
2
  R"g�}��\H]@�]g_aFv��(�+a`k!��Q�-B��o�Vy����@���#yL~e�JQL�^���J|�I�x��F"�7�~���B[Q $��*G�p� �.��[ 7e�E��FC�A �9C�
3
+
4
+ @?N�g>��(ʼn u)���Gw�^�P�S2o��nd�L�4O�`�Ӄ�W�mK�ι����jޮ�s�~Sz?mp2�
@@ -0,0 +1 @@
1
+ x}QMK�@���+��B�Ң�<X�y,e�m]�n�&K�w6&�h��0��{�m���������x����:�<72X�)�Nm�\<=?J�;nt~ �(B�l��/4M�5Z���K���*K�UDX�����P�b� �LE=�;�O��H���40�j�su�(s���z�V�b~L�2%J���W"�5g]�3����P�;^L�v:VB�]~�,K`���@f����e��܀NS��r��lEP��dB�J��ƽr�� ��(���=Ir�.g����-5��<$��,W��5�Ͷ�sF�8�F�J�F�F{�!��݈hO�1�W���_
@@ -0,0 +1,2 @@
1
+ x}�OK1Žn?��^ZXO���A��
2
+ ���&��hvS�l����N�V���余oi���./��ãU�����c�0�Km0���`�)8��u�^)��(8d�]�.?�m`����X��g��$���S>��Ϧ�~�ϣ)�h$�`���⍨ѯ�@YؿG�}'Nt ?�#Cv��%�[� ����VĆ��?w�a��:�^lT7�t; ��D�#�ޠ���
@@ -0,0 +1,2 @@
1
+ x��MK1��n~�P�PR؋X��(�x[J�fG6�&5�U����l�Tڃ�
2
+ ��z��Ie\�Wř��V{�<,Q������ �O+BL�`}��|}�QJ[�������j�h�r6�o9?���U�E��ΗC�X�� �0�2m�ik����D^H�0�a�P�0~��E��f,�k\kj�V��F"H��-a�g�p/C�Q�(�����w�.��0��<��{���I��� �<��8�[���>3���Y�ز#���Y�����H�^k��[Rѓ���8'��rK�5t��B�-!��X\�M��'�s���)�p@����`r�������}5 �o�}�`ў���h�3K
data/.git/packed-refs ADDED
@@ -0,0 +1,2 @@
1
+ # pack-refs with: peeled
2
+ 1196367828af7cc11276833728accd41428b60df refs/remotes/origin/master
@@ -0,0 +1 @@
1
+ 06864a068d188ab7ae17e39d58d6c25dc49a8ff3
@@ -0,0 +1 @@
1
+ ref: refs/remotes/origin/master
@@ -0,0 +1 @@
1
+ 06864a068d188ab7ae17e39d58d6c25dc49a8ff3
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *~
2
+ .DS_Store
3
+ .idea
4
+ .idea/**/*
5
+ Thumbs.db
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ Set of common Ruby language extensions.
2
+
3
+ For docs go to spec.
data/Rakefile ADDED
@@ -0,0 +1,64 @@
1
+ require 'rake'
2
+ require 'spec/rake/spectask'
3
+
4
+ Dir.chdir File.dirname(__FILE__)
5
+
6
+ # Specs
7
+ task :default => :spec
8
+
9
+ Spec::Rake::SpecTask.new('spec') do |t|
10
+ t.spec_files = FileList["spec/**/*_spec.rb"]
11
+ t.libs = ["lib", "spec"]
12
+ end
13
+
14
+ # Gem
15
+ require 'rake/clean'
16
+ require 'rake/gempackagetask'
17
+ require 'fileutils'
18
+
19
+ spec = Gem::Specification.new do |s|
20
+ s.name = "ruby-ext"
21
+ s.version = "0.2.0"
22
+ s.summary = "Set of common Ruby language extensions"
23
+ s.description = "Set of common Ruby language extensions"
24
+ s.author = "Alexey Petrushin"
25
+ # s.email = ""
26
+ s.homepage = "http://www.bos-tec.com"
27
+ # s.rubyforge_project = "RubyExt"
28
+
29
+ s.platform = Gem::Platform::RUBY
30
+ s.has_rdoc = true
31
+ s.extra_rdoc_files = ["README.rdoc"]
32
+
33
+ s.files = (%w{Rakefile README.rdoc .gitignore} + Dir.glob("{lib,spec,.git}/**/*"))
34
+ # s.executables = ['restclient']
35
+ # s.add_dependency("BlueCloth", ">= 0.0.4")
36
+ # s.add_dependency "facets"
37
+
38
+ s.require_path = "lib"
39
+ end
40
+
41
+ PACKAGE_DIR = "#{File.expand_path File.dirname(__FILE__)}/build"
42
+
43
+ Rake::GemPackageTask.new(spec) do |p|
44
+ package_dir = PACKAGE_DIR
45
+ # FileUtils.mkdir package_dir unless File.exist? package_dir
46
+ p.need_tar = true if RUBY_PLATFORM !~ /mswin/
47
+ p.need_zip = true
48
+ p.package_dir = package_dir
49
+ end
50
+
51
+ # CLEAN.include [ 'pkg', '*.gem']
52
+
53
+ task :push do
54
+ dir = Dir.chdir PACKAGE_DIR do
55
+ gem_file = Dir.glob("ruby-ext*.gem").first
56
+ system "gem push #{gem_file}"
57
+ end
58
+ end
59
+
60
+ task :clean do
61
+ system "rm -r #{PACKAGE_DIR}"
62
+ end
63
+
64
+ task :release => [:gem, :push, :clean]
@@ -0,0 +1,167 @@
1
+ require 'monitor'
2
+
3
+ module DeclarativeCache
4
+ DISABLED = false
5
+
6
+ warn "CASHE DISABLED" if DISABLED
7
+
8
+ # It's not a good idea to mix Business Logic and Performance optimization,
9
+ # so i think these methods should be never used.
10
+ # def cached *methods
11
+ # DeclarativeCache.cached self, *methods
12
+ # end
13
+ #
14
+ # def cached_with_params *methods
15
+ # DeclarativeCache.cached_with_params self, *methods
16
+ # end
17
+
18
+ @versions, @alias_counter, @monitor = Hash.new{should! :be_never_called}, 0, Monitor.new
19
+ class << self
20
+
21
+ def alias_counter
22
+ @alias_counter += 1
23
+ return :"m#{@alias_counter}"
24
+ end
25
+
26
+ def cached *arg
27
+ vnames, klass, methods = parse_and_check_arguments *arg
28
+
29
+ return if DISABLED
30
+ methods.each do |m|
31
+ als = (m.to_s =~ /^[_a-zA-Z0-9]+$/) ? m : DeclarativeCache.alias_counter.to_sym
32
+
33
+ klass.class_eval{alias_method :"cached_#{als}", :"#{m}"}
34
+ unless vnames.is_a? Array
35
+ script = single_version_without_args.substitute binding
36
+ @versions[vnames] = 0 unless @versions.include? vnames
37
+ else
38
+ vnames_str = vnames.collect{|vname| "'#{vname}' => nil"}.join(', ')
39
+ script = multiple_version_without_args.substitute binding
40
+ vnames.each{|vname| @versions[vname] = 0 unless @versions.include? vname}
41
+ end
42
+ klass.class_eval script, __FILE__, __LINE__
43
+ end
44
+ end
45
+
46
+ def cached_with_params *arg
47
+ vnames, klass, methods = parse_and_check_arguments *arg
48
+
49
+ return if DISABLED
50
+ methods.each do |m|
51
+ als = (m.to_s =~ /^[_a-zA-Z0-9]+$/) ? m : DeclarativeCache.alias_counter
52
+
53
+ klass.class_eval{alias_method :"cached_#{als}", :"#{m}"}
54
+ unless vnames.is_a? Array
55
+ script = single_version_with_args.substitute binding
56
+ @versions[vnames] = 0 unless @versions.include? vnames
57
+ else
58
+ vnames_str = vnames.collect{|vname| "'#{vname}' => nil"}.join(', ')
59
+ script = multiple_version_with_args.substitute binding
60
+ vnames.each{|vname| @versions[vname] = 0 unless @versions.include? vname}
61
+ end
62
+ klass.class_eval script, __FILE__, __LINE__
63
+ end
64
+ end
65
+
66
+ def version name
67
+ @versions[name]
68
+ end
69
+
70
+ def update *names
71
+ names.each do |n|
72
+ n = n.to_s
73
+ @versions[n] = 0 unless @versions.include? n
74
+ @versions[n] += 1
75
+ end
76
+ end
77
+
78
+ attr_reader :monitor
79
+
80
+ protected
81
+ def parse_and_check_arguments *arg
82
+ arg.size.should! :>=, 3
83
+
84
+ version_names = arg[0]
85
+ if version_names.is_a? Array
86
+ version_names.size.should! :>, 0
87
+ version_names = version_names.collect{|n| n.to_s}
88
+ else
89
+ version_names = version_names.to_s
90
+ end
91
+
92
+ klass = arg[1]
93
+ klass.class.should! :be, [Class, Module]
94
+
95
+ methods = arg[2..arg.size]
96
+ defined = klass.instance_methods
97
+ methods.each do |m|
98
+ raise "Invalid method_name '#{m}'!" unless defined.include? m.to_s
99
+ end
100
+ return version_names, klass, methods
101
+ end
102
+
103
+ def multiple_version_with_args
104
+ <<-RUBY
105
+ def \#{m} *params
106
+ DeclarativeCache.monitor.synchronize do
107
+ @cache_versions_\#{als} ||= {\#{vnames_str}}
108
+ @cache_value_\#{als} ||= {}
109
+ if @cache_versions_\#{als}.all?{|vname, v| v == DeclarativeCache.version(vname)} and @cache_value_\#{als}.include?(params)
110
+ return @cache_value_\#{als}[params]
111
+ else
112
+ @cache_versions_\#{als}.keys.each{|vname| @cache_versions_\#{als}[vname] = DeclarativeCache.version(vname)}
113
+ return @cache_value_\#{als}[params] = cached_\#{als}(*params)
114
+ end
115
+ end
116
+ end
117
+ RUBY
118
+ end
119
+
120
+ def multiple_version_without_args
121
+ <<-RUBY
122
+ def \#{m}
123
+ DeclarativeCache.monitor.synchronize do
124
+ @cache_versions_\#{als} ||= {\#{vnames_str}}
125
+ if @cache_versions_\#{als}.all?{|vname, v| v == DeclarativeCache.version(vname)}
126
+ return @cache_value_\#{als}
127
+ else
128
+ @cache_versions_\#{als}.keys.each{|vname| @cache_versions_\#{als}[vname] = DeclarativeCache.version(vname)}
129
+ return @cache_value_\#{als} = cached_\#{als}
130
+ end
131
+ end
132
+ end
133
+ RUBY
134
+ end
135
+
136
+ def single_version_with_args
137
+ <<-RUBY
138
+ def \#{m} *params
139
+ DeclarativeCache.monitor.synchronize do
140
+ @cache_value_\#{als} ||= {}
141
+ if @cache_version_\#{als} == DeclarativeCache.version("\#{vnames}") and @cache_value_\#{als}.include?(params)
142
+ return @cache_value_\#{als}[params]
143
+ else
144
+ @cache_version_\#{als} = DeclarativeCache.version("\#{vnames}")
145
+ return @cache_value_\#{als}[params] = cached_\#{als}(*params)
146
+ end
147
+ end
148
+ end
149
+ RUBY
150
+ end
151
+
152
+ def single_version_without_args
153
+ <<-RUBY
154
+ def \#{m}
155
+ DeclarativeCache.monitor.synchronize do
156
+ if @cache_version_\#{als} == DeclarativeCache.version("\#{vnames}")
157
+ return @cache_value_\#{als}
158
+ else
159
+ @cache_version_\#{als} = DeclarativeCache.version("\#{vnames}")
160
+ return @cache_value_\#{als} = cached_\#{als}
161
+ end
162
+ end
163
+ end
164
+ RUBY
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,23 @@
1
+ class File
2
+ class << self
3
+ def write(path, data)
4
+ File.open(path, "wb") do |file|
5
+ return file.write(data)
6
+ end
7
+ end
8
+
9
+ def read(path)
10
+ File.open(path, "rb") do |file|
11
+ return file.read
12
+ end
13
+ end
14
+
15
+ def create_directory dir
16
+ Dir.mkdir dir unless File.exist? dir
17
+ end
18
+
19
+ def delete_directory dir
20
+ FileUtils.rm_r dir, :force => true if File.exist? dir
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Kernel
2
+ def respond_to sym, *args
3
+ return nil if not respond_to? sym
4
+ send sym, *args
5
+ end
6
+
7
+ # def _ &b
8
+ # raise "Block isn't provided!" unless b
9
+ # return b
10
+ # end
11
+
12
+ def singleton_class(&block)
13
+ if block_given?
14
+ (class << self; self; end).class_eval(&block)
15
+ self
16
+ else
17
+ (class << self; self; end)
18
+ end
19
+ end
20
+ alias_method :metaclass, :singleton_class
21
+ end
@@ -0,0 +1,84 @@
1
+ require 'set'
2
+
3
+ class Module
4
+ def is?(base)
5
+ ancestors.include?(base)
6
+ end
7
+
8
+ def wrap_method( sym, prefix = "old_", &blk )
9
+ old_method = "#{prefix}_#{sym}".to_sym
10
+ alias_method old_method, sym
11
+ define_method(sym) do |*args|
12
+ instance_exec(old_method, *args, &blk)
13
+ end
14
+ end
15
+
16
+ def inherited_instance_methods
17
+ im = Set.new
18
+ ancestors.each do |a|
19
+ next if a == self
20
+ im.merge a.instance_methods
21
+ end
22
+ return im.to_a
23
+ end
24
+
25
+ def namespace
26
+ if @module_namespace_defined
27
+ @module_namespace
28
+ else
29
+ @module_namespace_defined = true
30
+ @module_namespace = Module.namespace_for name
31
+ end
32
+ end
33
+
34
+ def each_namespace &block
35
+ current = namespace
36
+ while current do
37
+ block.call current
38
+ current = current.namespace
39
+ end
40
+ end
41
+
42
+ def each_ancestor include_standard = false, &block
43
+ if include_standard
44
+ ancestors.each{|a| block.call a unless a == self}
45
+ else
46
+ exclude = [self, Object, Kernel]
47
+ ancestors.each do |a|
48
+ block.call a unless exclude.include? a
49
+ end
50
+ end
51
+ end
52
+
53
+ def self_ancestors_and_namespaces &b
54
+ b.call self
55
+ each_ancestor &b
56
+ each_namespace &b
57
+ end
58
+
59
+ def self.namespace_for class_name
60
+ list = class_name.split("::")
61
+ if list.size > 1
62
+ list.pop
63
+ return eval list.join("::"), TOPLEVEL_BINDING, __FILE__, __LINE__
64
+ else
65
+ return nil
66
+ end
67
+ end
68
+
69
+ def inherit *modules
70
+ modules.each do |amodule|
71
+ include amodule
72
+
73
+ processed = []
74
+ amodule.ancestors.each do |a|
75
+ if a.const_defined? :ClassMethods
76
+ class_methods = a.const_get :ClassMethods
77
+ next if processed.include? class_methods
78
+ processed << class_methods
79
+ extend class_methods
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,2 @@
1
+ module NotDefined
2
+ end
@@ -0,0 +1,7 @@
1
+ class Object
2
+ def self; self end
3
+
4
+ # def copy
5
+ # Marshal.load(Marshal.dump self) # Stub
6
+ # end
7
+ end
@@ -0,0 +1,51 @@
1
+ module OpenConstructor
2
+ def set values, list = nil
3
+ unless list
4
+ if values.is_a? Hash
5
+ values.each do |k, v|
6
+ self.respond_to k.to_writer, v
7
+ end
8
+ else
9
+ values.instance_variables.each do |name|
10
+ accessor = name[1..name.size].to_writer
11
+ if self.respond_to? accessor
12
+ self.send accessor, values.instance_variable_get(name)
13
+ end
14
+ end
15
+ end
16
+ else
17
+ if values.is_a? Hash
18
+ values.each do |k, v|
19
+ self.respond_to k.to_writer, v if list.include? k
20
+ end
21
+ else
22
+ values.instance_variables.each do |name|
23
+ accessor = name[1..name.size]
24
+ if list.include?(accessor.to_sym)
25
+ accessor = accessor.to_writer
26
+ if self.respond_to?(accessor)
27
+ self.send accessor, values.instance_variable_get(name)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ return self
34
+ end
35
+
36
+ def set_with_check values
37
+ values.each do |k, v|
38
+ self.send k.to_writer, v
39
+ end
40
+ return self
41
+ end
42
+ alias_method :set!, :set_with_check
43
+
44
+ def to_hash
45
+ hash = {}
46
+ instance_variables.each do |name|
47
+ hash[name[1..name.size].to_sym] = instance_variable_get name
48
+ end
49
+ return hash
50
+ end
51
+ end
@@ -0,0 +1,105 @@
1
+ class ArgumentsParser
2
+ class << self
3
+ def register method, arguments
4
+ # check and prepare metadata
5
+ arguments.collect!{|meta| meta.is_a?(Hash) ? meta : {:type => meta}}
6
+ arguments.each{|meta| meta.should! :include, :type}
7
+
8
+ # register
9
+ @registry ||= {}
10
+ @registry[method] = arguments
11
+ end
12
+
13
+ def parse_arguments_for method, *args, &block
14
+ metadata = @registry[method]
15
+ index = 0
16
+ parsed_args = metadata.collect do |options|
17
+ send options[:type], args, block, options, index, (index == metadata.size - 1)
18
+ end
19
+ args.should_be! :empty
20
+ return parsed_args
21
+ end
22
+
23
+ protected
24
+ def string args, block, options, index, last
25
+ object(args, block, options, index, last) || ""
26
+ end
27
+
28
+ def object args, block, options, index, last
29
+ a = if range = options[:range]
30
+ if range == :except_last_hash
31
+ if args.size == 1 and args.last.is_a? Hash
32
+ nil
33
+ else
34
+ args.shift
35
+ end
36
+ else
37
+ should_be! :never_called
38
+ end
39
+ else
40
+ args.shift
41
+ end
42
+
43
+ a = _common_options a, options
44
+ a
45
+ end
46
+
47
+ def array args, block, options, index, last
48
+ a = if last
49
+ args
50
+ elsif range = options[:range]
51
+ if range == :except_last_hash
52
+ if args.last.is_a? Hash
53
+ tmp = args[0..-2]
54
+ args[0..-2] = nil
55
+ tmp
56
+ else
57
+ tmp = args[0..-1]
58
+ args.clear
59
+ tmp
60
+ end
61
+ else
62
+ should_be! :never_called
63
+ end
64
+ else
65
+ args.shift
66
+ end
67
+
68
+ a = _common_options a, options
69
+ a ||= []
70
+ a = [a] unless a.is_a?(Array)
71
+ a
72
+ end
73
+
74
+ def hash args, block, options, index, last
75
+ a = object(args, block, options, index, last) || {}
76
+ a.should! :be_a, Hash
77
+ a
78
+ end
79
+
80
+ def _common_options a, options
81
+ a.should_not! :be_nil if options[:require]
82
+ if (default = options[:default]) and a.eql?(nil)
83
+ a = default
84
+ end
85
+ a
86
+ end
87
+ end
88
+ end
89
+
90
+ class Object
91
+ def self.prepare_arguments_for method, *args
92
+ # Register parsers
93
+ ArgumentsParser.register method, args
94
+
95
+ # Wrap method
96
+ old_method = :"#{method}_wparg"
97
+ alias_method old_method, method
98
+ code = <<END
99
+ def #{method} *args, &block
100
+ #{old_method} *ArgumentsParser.parse_arguments_for(:#{method}, *args), &block
101
+ end
102
+ END
103
+ class_eval code, __FILE__, __LINE__
104
+ end
105
+ end