arrayclass 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +13 -0
- data/README +55 -0
- data/Rakefile +234 -0
- data/lib/arrayclass.rb +106 -0
- data/specs/arrayclass_spec.rb +13 -0
- data/specs/light_class_shared.rb +152 -0
- data/specs/spec_helper.rb +57 -0
- metadata +62 -0
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2007, The University of Texas at Austin("U.T. Austin"). All rights reserved.
|
2
|
+
|
3
|
+
Software by John T. Prince under the direction of Edward M. Marcotte.
|
4
|
+
|
5
|
+
By using this software the USER indicates that he or she has read, understood and will comply with the following:
|
6
|
+
|
7
|
+
U. T. Austin hereby grants USER permission to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of this software and its documentation for any purpose and without fee, provided that a full copy of this notice is included with the software and its documentation.
|
8
|
+
|
9
|
+
Title to copyright this software and its associated documentation shall at all times remain with U. T. Austin. No right is granted to use in advertising, publicity or otherwise any trademark, service mark, or the name of U. T. Austin.
|
10
|
+
|
11
|
+
This software and any associated documentation are provided "as is," and U. T. AUSTIN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING THOSE OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT USE OF THE SOFTWARE, MODIFICATIONS, OR ASSOCIATED DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER INTELLECTUAL PROPERTY RIGHTS OF A THIRD PARTY. U. T. Austin, The University of Texas System, its Regents, officers, and employees shall not be liable under any circumstances for any direct, indirect, special, incidental, or consequential damages with respect to any claim by USER or any third party on account of or arising from the use, or inability to use, this software or its associated documentation, even if U. T. Austin has been advised of the possibility of those damages.
|
12
|
+
|
13
|
+
Submit software operation questions to: Edward M. Marcotte, Department of Chemistry and Biochemistry, U. T. Austin, Austin, Texas 78712.
|
data/README
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
Arrayclass
|
2
|
+
==========
|
3
|
+
|
4
|
+
Arrayclass is a class factory for generating Array based objects whose attributes can be accessed like those of a normal ruby object (or like an array). They are highly memory efficient (almost equivalent to an Array) and fast to work with.
|
5
|
+
|
6
|
+
Features
|
7
|
+
--------
|
8
|
+
|
9
|
+
Arrayclass based objects are:
|
10
|
+
* memory efficient - roughly the same space as a normal array
|
11
|
+
* quickly instantiated with data
|
12
|
+
|
13
|
+
Examples
|
14
|
+
--------
|
15
|
+
|
16
|
+
require 'arrayclass'
|
17
|
+
|
18
|
+
Person = Arrayclass.new(%w(name eye_color watch_brand))
|
19
|
+
# instantiate with an array
|
20
|
+
joe = Person.new(%w(Joe brown Casio))
|
21
|
+
|
22
|
+
# instantiate an empty object (an array of the expected size is created)
|
23
|
+
sally = Person.new
|
24
|
+
sally.name = 'Sally'
|
25
|
+
sally[0] == 'Sally' # true
|
26
|
+
|
27
|
+
### Access/modify attributes like a normal object
|
28
|
+
|
29
|
+
joe.name # 'Joe'
|
30
|
+
joe.watch_brand = 'Timex'
|
31
|
+
|
32
|
+
### Use some array features
|
33
|
+
|
34
|
+
joe[1] # 'brown'
|
35
|
+
joe[1..2] = ['blue', 'Fossil']
|
36
|
+
joe.each {|attribute| # do something with attribute }
|
37
|
+
|
38
|
+
### Arrayclass derived classes can be subclassed
|
39
|
+
|
40
|
+
class BigPerson < Person
|
41
|
+
def some_new_function
|
42
|
+
end
|
43
|
+
|
44
|
+
# push on another attribute
|
45
|
+
self.add_member('shoe_type')
|
46
|
+
|
47
|
+
# (haven't written a remove_member function yet...)
|
48
|
+
end
|
49
|
+
|
50
|
+
BigPerson.new
|
51
|
+
|
52
|
+
Installation
|
53
|
+
------------
|
54
|
+
|
55
|
+
gem install arrayclass
|
data/Rakefile
ADDED
@@ -0,0 +1,234 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/clean'
|
6
|
+
require 'spec/rake/spectask'
|
7
|
+
require 'email_encrypt'
|
8
|
+
|
9
|
+
require 'fileutils'
|
10
|
+
|
11
|
+
###############################################
|
12
|
+
# GLOBAL
|
13
|
+
###############################################
|
14
|
+
|
15
|
+
FL = FileList
|
16
|
+
NAME = "arrayclass"
|
17
|
+
FU = FileUtils
|
18
|
+
|
19
|
+
readme = "README"
|
20
|
+
|
21
|
+
rdoc_extra_includes = [readme, "LICENSE"]
|
22
|
+
rdoc_options = ['--main', readme, '--title', NAME]
|
23
|
+
|
24
|
+
lib_files = FL["lib/**/*"]
|
25
|
+
dist_files = lib_files + FL[readme, "LICENSE", "Rakefile", "{specs}/**/*"]
|
26
|
+
changelog = 'CHANGELOG'
|
27
|
+
|
28
|
+
###############################################
|
29
|
+
# ENVIRONMENT
|
30
|
+
###############################################
|
31
|
+
ENV["OS"] == "Windows_NT" ? WIN32 = true : WIN32 = false
|
32
|
+
$gemcmd = "gem"
|
33
|
+
if WIN32
|
34
|
+
unless ENV["TERM"] == "cygwin"
|
35
|
+
$gemcmd << ".cmd"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
###############################################
|
41
|
+
# DOC
|
42
|
+
###############################################
|
43
|
+
Rake::RDocTask.new do |rd|
|
44
|
+
rd.main = readme
|
45
|
+
rd.rdoc_files.include rdoc_extra_includes
|
46
|
+
rd.options.push( *rdoc_options )
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "create html docs"
|
50
|
+
task :html_docs do
|
51
|
+
css = 'doc/src/style.css'
|
52
|
+
FU.mkpath 'doc/output'
|
53
|
+
FU.cp css, 'doc/output/'
|
54
|
+
index = 'doc/output/index.html'
|
55
|
+
header = 'doc/src/header'
|
56
|
+
File.open(index, 'w') do |index|
|
57
|
+
index.puts '<html>'
|
58
|
+
index.puts IO.read(header)
|
59
|
+
index.puts '<html><body>'
|
60
|
+
index.puts `bluecloth --fragment #{readme}`
|
61
|
+
|
62
|
+
# add contact info:
|
63
|
+
index.puts '<h2>Contact</h2>'
|
64
|
+
index.puts 'jtprince@gmail.com'.email_encrypt
|
65
|
+
|
66
|
+
index.puts '</body></html>'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "create and upload docs to server"
|
71
|
+
task :upload_docs => :html_docs do
|
72
|
+
sh "scp -i ~/.ssh/rubyforge_key -r doc/output/* jtprince@rubyforge.org:/var/www/gforge-projects/arrayclass/"
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
###############################################
|
77
|
+
# TESTS
|
78
|
+
###############################################
|
79
|
+
|
80
|
+
|
81
|
+
task :ensure_gem_is_uninstalled do
|
82
|
+
reply = `#{$gemcmd} list -l #{NAME}`
|
83
|
+
if reply.include? NAME + " ("
|
84
|
+
puts "GOING to uninstall gem '#{NAME}' for testing"
|
85
|
+
if WIN32
|
86
|
+
%x( #{$gemcmd} uninstall -x #{NAME} )
|
87
|
+
else
|
88
|
+
%x( sudo #{$gemcmd} uninstall -x #{NAME} )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
namespace :spec do
|
94
|
+
task :autotest do
|
95
|
+
require './specs/rspec_autotest'
|
96
|
+
RspecAutotest.run
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
desc "Run specs"
|
101
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
102
|
+
Rake::Task[:ensure_gem_is_uninstalled].invoke
|
103
|
+
t.libs = ['lib']
|
104
|
+
t.spec_files = FileList['specs/**/*_spec.rb']
|
105
|
+
end
|
106
|
+
|
107
|
+
desc "Run specs and output specdoc"
|
108
|
+
Spec::Rake::SpecTask.new('specl') do |t|
|
109
|
+
Rake::Task[:ensure_gem_is_uninstalled].invoke
|
110
|
+
t.spec_files = FileList['specs/**/*_spec.rb']
|
111
|
+
t.libs = ['lib']
|
112
|
+
t.spec_opts = ['--format', 'specdoc' ]
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "Run all specs with RCov"
|
116
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
117
|
+
Rake::Task[:ensure_gem_is_uninstalled].invoke
|
118
|
+
t.spec_files = FileList['specs/**/*_spec.rb']
|
119
|
+
t.rcov = true
|
120
|
+
t.libs = ['lib']
|
121
|
+
t.rcov_opts = ['--exclude', 'specs']
|
122
|
+
end
|
123
|
+
|
124
|
+
#task :spec do
|
125
|
+
# uninstall_gem
|
126
|
+
# # files that match a key word
|
127
|
+
# files_to_run = ENV['SPEC'] || FileList['specs/**/*_spec.rb']
|
128
|
+
# if ENV['SPECM']
|
129
|
+
# files_to_run = files_to_run.select do |file|
|
130
|
+
# file.include?(ENV['SPECM'])
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
# files_to_run.each do |spc|
|
134
|
+
# system "ruby -I lib -S spec #{spc} --format specdoc"
|
135
|
+
# end
|
136
|
+
#end
|
137
|
+
|
138
|
+
###############################################
|
139
|
+
# PACKAGE / INSTALL / UNINSTALL
|
140
|
+
###############################################
|
141
|
+
|
142
|
+
def get_summary(readme)
|
143
|
+
string = ''
|
144
|
+
collect = false
|
145
|
+
IO.foreach(readme) do |line|
|
146
|
+
if collect
|
147
|
+
if line =~ /[^\s]/
|
148
|
+
string << line
|
149
|
+
else
|
150
|
+
break
|
151
|
+
end
|
152
|
+
elsif line =~ /^AXML - .*/
|
153
|
+
string << line
|
154
|
+
collect = true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
string.gsub!("\n", " ")
|
158
|
+
end
|
159
|
+
|
160
|
+
# looks for a header, collects the paragraph after the space
|
161
|
+
def get_section(header, file)
|
162
|
+
get_space = false
|
163
|
+
found_space = false
|
164
|
+
string = ''
|
165
|
+
IO.foreach(file) do |line|
|
166
|
+
if found_space
|
167
|
+
if line =~ /[^\s]/
|
168
|
+
string << line
|
169
|
+
else
|
170
|
+
break
|
171
|
+
end
|
172
|
+
elsif get_space
|
173
|
+
if line !~ /[^\s]/
|
174
|
+
found_space = true
|
175
|
+
get_space = false
|
176
|
+
end
|
177
|
+
elsif line =~ /^#{header}/
|
178
|
+
get_space = true
|
179
|
+
end
|
180
|
+
end
|
181
|
+
string.gsub!("\n", ' ')
|
182
|
+
end
|
183
|
+
|
184
|
+
def get_description(readme)
|
185
|
+
get_section('Description', readme)
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
tm = Time.now
|
190
|
+
|
191
|
+
desc "Create packages."
|
192
|
+
gemspec = Gem::Specification.new do |t|
|
193
|
+
t.platform = Gem::Platform::RUBY
|
194
|
+
t.name = NAME
|
195
|
+
t.rubyforge_project = NAME
|
196
|
+
t.version = IO.readlines(changelog).grep(/##.*version/).pop.split(/\s+/).last.chomp
|
197
|
+
t.homepage = "http://arrayclass.rubyforge.org"
|
198
|
+
t.date = "#{tm.year}-#{tm.month}-#{tm.day}"
|
199
|
+
t.summary = "low memory class based on Array"
|
200
|
+
t.email = "jtprince@gmail.com"
|
201
|
+
t.has_rdoc = true
|
202
|
+
t.authors = ['John Prince']
|
203
|
+
t.files = dist_files
|
204
|
+
t.test_files = FL["specs/*_spec.rb"]
|
205
|
+
t.rdoc_options = rdoc_options
|
206
|
+
end
|
207
|
+
|
208
|
+
desc "Create packages."
|
209
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
210
|
+
pkg.need_zip = true
|
211
|
+
pkg.need_tar = true
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
|
216
|
+
task :remove_pkg do
|
217
|
+
FileUtils.rm_rf "pkg"
|
218
|
+
end
|
219
|
+
|
220
|
+
task :install => [:reinstall]
|
221
|
+
|
222
|
+
desc "uninstalls the package, packages a fresh one, and installs"
|
223
|
+
task :reinstall => [:remove_pkg, :clean, :package] do
|
224
|
+
reply = `#{$gemcmd} list -l #{NAME}`
|
225
|
+
if reply.include?(NAME + " (")
|
226
|
+
%x( #{$gemcmd} uninstall -a -x #{NAME} )
|
227
|
+
end
|
228
|
+
FileUtils.cd("pkg") do
|
229
|
+
cmd = "#{$gemcmd} install #{NAME}*.gem"
|
230
|
+
puts "EXECUTING: #{cmd}"
|
231
|
+
system cmd
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
data/lib/arrayclass.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
|
2
|
+
class Array
|
3
|
+
|
4
|
+
undef_method :flatten
|
5
|
+
undef_method :flatten!
|
6
|
+
#tmp_verb = $VERBOSE
|
7
|
+
#$VERBOSE = nil
|
8
|
+
# WARNING! Array#flatten is redefined so that it calls the is_a? method
|
9
|
+
# (instead of doing it internally as defined in the C code). This allows
|
10
|
+
# Arrayclass derived objects to resist flattening by declaring that they are
|
11
|
+
# not Arrays. This may be _slightly_ slower than the original, but in all
|
12
|
+
# other respects should be the same (i.e., will flatten array derived
|
13
|
+
# classes).
|
14
|
+
def flatten
|
15
|
+
new_array = []
|
16
|
+
self.each do |v|
|
17
|
+
if v.is_a?(Array)
|
18
|
+
new_array.push( *(v.flatten) )
|
19
|
+
else
|
20
|
+
new_array << v
|
21
|
+
end
|
22
|
+
end
|
23
|
+
new_array
|
24
|
+
end
|
25
|
+
|
26
|
+
# WARNING! Array#flatten! is redefined flatten method discussed above.
|
27
|
+
def flatten!
|
28
|
+
self.replace(flatten)
|
29
|
+
end
|
30
|
+
#$VERBOSE = tmp_verb
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
module Arrayclass
|
35
|
+
def self.new(fields)
|
36
|
+
nclass = Class.new(Array)
|
37
|
+
|
38
|
+
nclass.class_eval('def self.add_member(name)
|
39
|
+
i = @@arr_size
|
40
|
+
self.class_eval("def #{name}() self[#{i}] end")
|
41
|
+
self.class_eval("def #{name}=(val) self[#{i}]=val end")
|
42
|
+
self.class_eval("@@ind[:#{name}] = #{i}")
|
43
|
+
self.class_eval("@@ind[\"#{name}\"] = #{i}")
|
44
|
+
self.class_eval("@@attributes << :#{name}")
|
45
|
+
self.class_eval("@@arr_size = @@attributes.size")
|
46
|
+
end')
|
47
|
+
|
48
|
+
|
49
|
+
# This list is derived from ImageList in ImageMagick (and I've added some
|
50
|
+
# applicable to this guy) (I've left zip here as it is applicable and a
|
51
|
+
# great method)
|
52
|
+
%w(flatten flatten! assoc join rassoc push pop <<).each do |att|
|
53
|
+
nclass.class_eval("undef_method :#{att}")
|
54
|
+
end
|
55
|
+
nclass.class_eval("undef_method :transpose if Array.instance_methods(false).include?('transpose')")
|
56
|
+
nclass.class_eval("@@ind = {}")
|
57
|
+
# array to preserve order
|
58
|
+
nclass.class_eval("@@attributes = []")
|
59
|
+
nclass.class_eval("@@arr_size = 0")
|
60
|
+
fields.each_with_index do |field,i|
|
61
|
+
nclass.add_member(field.to_s)
|
62
|
+
end
|
63
|
+
#nclass.class_eval('@@ind.each do |k,v| @@ind["#{k}"] = v end ')
|
64
|
+
nclass.class_eval "
|
65
|
+
def initialize(args=nil)
|
66
|
+
if args.is_a? Array
|
67
|
+
super(args)
|
68
|
+
elsif args.is_a? Hash
|
69
|
+
super(@@arr_size)
|
70
|
+
args.each do |k,v|
|
71
|
+
self[@@ind[k]] = v
|
72
|
+
end
|
73
|
+
else
|
74
|
+
super(@@arr_size)
|
75
|
+
end
|
76
|
+
end"
|
77
|
+
|
78
|
+
# list of
|
79
|
+
nclass.class_eval('def self.members() @@attributes end')
|
80
|
+
nclass.class_eval('def members() @@attributes end')
|
81
|
+
nclass.class_eval("def is_a?(klass)
|
82
|
+
if klass == Array ; false
|
83
|
+
else ; super(klass)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
alias_method :kind_of?, :is_a?")
|
87
|
+
|
88
|
+
nclass.class_eval('def inspect
|
89
|
+
bits = @@attributes.map do |v|
|
90
|
+
val = self.send(v)
|
91
|
+
val = "nil" if val.nil?
|
92
|
+
"#{v}=#{val.inspect}"
|
93
|
+
end
|
94
|
+
string = bits.join(", ")
|
95
|
+
"<(Arrayclass based) #{string}>"
|
96
|
+
end ')
|
97
|
+
#nclass.class_eval('def self.indices() @@ind end')
|
98
|
+
#nclass.class_eval('def indices() @@ind end')
|
99
|
+
|
100
|
+
# NOTE that two separate objects will hash differently (even if their
|
101
|
+
# content is the same!)
|
102
|
+
nclass.class_eval('def hash() object_id end')
|
103
|
+
nclass
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path( File.dirname(__FILE__) + '/spec_helper' )
|
2
|
+
require File.dirname(__FILE__) + '/light_class_shared'
|
3
|
+
|
4
|
+
require 'arrayclass'
|
5
|
+
|
6
|
+
|
7
|
+
describe ArrayClass do
|
8
|
+
before(:all) do
|
9
|
+
@generator = ArrayClass
|
10
|
+
end
|
11
|
+
it_should_behave_like 'a light memory class'
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
|
2
|
+
describe 'a light memory class', :shared => true do
|
3
|
+
before(:each) do
|
4
|
+
@attrs = %w(f0 f1 f2)
|
5
|
+
@attrs_as_symbols = @attrs.map {|v| v.to_sym }
|
6
|
+
@myclass = @generator.new(@attrs)
|
7
|
+
@init_array = [0,1,2]
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'can be initialized with an array' do
|
11
|
+
obj = @myclass.new(@init_array)
|
12
|
+
obj.f0.should == obj[0]
|
13
|
+
obj.f1.should == obj[1]
|
14
|
+
obj.f2.should == obj[2]
|
15
|
+
obj.f1 = 5
|
16
|
+
obj.f1.should == 5
|
17
|
+
obj.class.should == @myclass
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can be queried and modified by method call' do
|
21
|
+
obj = @myclass.new(@init_array)
|
22
|
+
obj.f0.should == 0
|
23
|
+
obj.f1.should == 1
|
24
|
+
obj.f2.should == 2
|
25
|
+
|
26
|
+
obj.f0 = 5
|
27
|
+
obj.f1 = 6
|
28
|
+
obj.f2 = 7
|
29
|
+
|
30
|
+
obj.f0.should == 5
|
31
|
+
obj.f1.should == 6
|
32
|
+
obj.f2.should == 7
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'can be queried and modified by array index' do
|
36
|
+
obj = @myclass.new(@init_array)
|
37
|
+
obj[0].should == 0
|
38
|
+
obj[1].should == 1
|
39
|
+
obj[2].should == 2
|
40
|
+
|
41
|
+
obj[0] = 5
|
42
|
+
obj[1] = 6
|
43
|
+
obj[2] = 7
|
44
|
+
|
45
|
+
obj[0].should == 5
|
46
|
+
obj[1].should == 6
|
47
|
+
obj[2].should == 7
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'can have methods added' do
|
51
|
+
MyClass = @generator.new([:one])
|
52
|
+
class MyClass
|
53
|
+
def hello() 'hiya' end
|
54
|
+
end
|
55
|
+
obj = MyClass.new
|
56
|
+
obj.hello.should == 'hiya'
|
57
|
+
# OR -->
|
58
|
+
#@myclass.class_eval("def hello() 'hiya' end")
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'can be initialized with a hash' do
|
62
|
+
## Hash initialization:
|
63
|
+
obj = @myclass.new(:f0 => 0, :f1 => 1, :f2 => 2)
|
64
|
+
obj.f0.should == 0
|
65
|
+
obj.f1.should == 1
|
66
|
+
obj.f2.should == 2
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'can set and retrieve multiple members in a single slice' do
|
70
|
+
obj = @myclass.new
|
71
|
+
obj[0,3] = [4,5,6]
|
72
|
+
obj[0].should == 4
|
73
|
+
obj[1].should == 5
|
74
|
+
obj[2].should == 6
|
75
|
+
obj[0..-1] = [7,8,9]
|
76
|
+
obj[0].should == 7
|
77
|
+
obj[1].should == 8
|
78
|
+
obj[2].should == 9
|
79
|
+
|
80
|
+
obj[0,2].should == [7,8]
|
81
|
+
obj[0..1].should == [7,8]
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'has a member list (like Struct)' do
|
85
|
+
obj = @myclass.new
|
86
|
+
obj.members.should == @attrs_as_symbols
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'does not respond to calls that would potentially mess up your object' do
|
90
|
+
%w(flatten flatten! assoc join rassoc push pop <<).each do |cl|
|
91
|
+
obj = @myclass.new
|
92
|
+
obj.respond_to?(cl.to_sym).should == false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'is resilient to flattening' do
|
97
|
+
## inside of arrays:
|
98
|
+
obj = @myclass.new([0,1,2])
|
99
|
+
y = @myclass.new([0,nil,1])
|
100
|
+
result = [[obj,[y]],nil].flatten
|
101
|
+
|
102
|
+
# [[0,1,2], [0,nil,1], nil]
|
103
|
+
# result.should == [[0,1,2], [0,nil,1], nil]
|
104
|
+
result[0][0].should == 0
|
105
|
+
result[0][1].should == 1
|
106
|
+
result[0][2].should == 2
|
107
|
+
|
108
|
+
result[1][0].should == 0
|
109
|
+
result[1][1].should == nil
|
110
|
+
result[1][2].should == 1
|
111
|
+
|
112
|
+
result[2].should == nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'is hashed like an object' do
|
116
|
+
# arrays are hashed by values so that identical arrays give same key:
|
117
|
+
hash = { [1,2,3] => 'dog'}
|
118
|
+
hash[[1,2,3]].should == hash[[1,2,3]]
|
119
|
+
|
120
|
+
# these are objects and so two different objects should hash different,
|
121
|
+
# even with the same values!
|
122
|
+
ar = [1,2,3]
|
123
|
+
one = @myclass.new(ar)
|
124
|
+
same_data_diff_object = @myclass.new(ar)
|
125
|
+
hash = { one => 'dog' }
|
126
|
+
hash[one].should == hash[one]
|
127
|
+
hash[one].should_not == hash[same_data_diff_object]
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'gives inspect (like Struct)' do
|
131
|
+
obj = @myclass.new
|
132
|
+
obj.f0 = 1
|
133
|
+
obj.f1 = 'string'
|
134
|
+
obj.inspect.should =~ /<.*f0=1, f1="string", f2="nil">/
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'can be inherited and add members' do
|
138
|
+
class Inherited < @myclass
|
139
|
+
self.add_member(:f3)
|
140
|
+
self.add_member(:f4)
|
141
|
+
end
|
142
|
+
obj = Inherited.new([0,-1,-2,1,2])
|
143
|
+
obj.f0.should == 0
|
144
|
+
obj[1].should == -1
|
145
|
+
obj.f3.should == 1
|
146
|
+
obj[4].should == 2
|
147
|
+
obj.is_a?(Inherited).should be_true
|
148
|
+
obj.is_a?(@myclass).should be_true
|
149
|
+
obj.is_a?(Array).should_not be_true
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
gem 'rspec'
|
3
|
+
|
4
|
+
|
5
|
+
def xdescribe(*args)
|
6
|
+
puts "#{args.join(' ')}"
|
7
|
+
puts "**SKIPPING**"
|
8
|
+
end
|
9
|
+
|
10
|
+
def Xdescribe(*args)
|
11
|
+
xdescribe(*args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def xit(*args)
|
15
|
+
puts "- SKIPPING: #{args.join(' ')}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def silent(&block)
|
19
|
+
tmp = $VERBOSE ; $VERBOSE = nil
|
20
|
+
block.call
|
21
|
+
$VERBOSE = tmp
|
22
|
+
end
|
23
|
+
|
24
|
+
silent {
|
25
|
+
ROOT_DIR = File.dirname(__FILE__) + '/..'
|
26
|
+
SPEC_DIR = File.dirname(__FILE__)
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
class String
|
31
|
+
#alias_method :exist?, exist_as_a_file?
|
32
|
+
#alias_method exist_as_a_file?, exist?
|
33
|
+
def exist?
|
34
|
+
File.exist? self
|
35
|
+
end
|
36
|
+
def exist_as_a_file?
|
37
|
+
File.exist? self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "a cmdline program", :shared => true do
|
42
|
+
before(:all) do
|
43
|
+
testdir = File.dirname(__FILE__)
|
44
|
+
libdir = testdir + '/../lib'
|
45
|
+
bindir = testdir + '/../bin'
|
46
|
+
progname = "fasta_shaker.rb"
|
47
|
+
@cmd = "ruby -I #{libdir} #{bindir}/#{@progname} "
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'gives usage when called with no args' do
|
51
|
+
reply = `#{@cmd}`
|
52
|
+
reply.should =~ /usage/i
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arrayclass
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- John Prince
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-07-14 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: jtprince@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/arrayclass.rb
|
26
|
+
- README
|
27
|
+
- LICENSE
|
28
|
+
- Rakefile
|
29
|
+
- specs/spec_helper.rb
|
30
|
+
- specs/arrayclass_spec.rb
|
31
|
+
- specs/light_class_shared.rb
|
32
|
+
has_rdoc: true
|
33
|
+
homepage: http://arrayclass.rubyforge.org
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options:
|
36
|
+
- --main
|
37
|
+
- README
|
38
|
+
- --title
|
39
|
+
- arrayclass
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
requirements: []
|
55
|
+
|
56
|
+
rubyforge_project: arrayclass
|
57
|
+
rubygems_version: 1.1.1
|
58
|
+
signing_key:
|
59
|
+
specification_version: 2
|
60
|
+
summary: low memory class based on Array
|
61
|
+
test_files:
|
62
|
+
- specs/arrayclass_spec.rb
|