Probably total sacrilege, but I was using this to have "nil" as a
valid value in arithmetic and to treat numbers as if they were
arrays (in a limited sense). The latter is easy to fix, by storing
all numbers as 1 element arrays. This solves the iterator on "nil"
too. All nil values will be in an array, so I just need to iterate on
the array.
Using "nil" in arithmetic is to differentiate the no data state
(nil), from having seen a data point, even a 0 value. Probably best
to subclass Fixnum and build my own objects for arithmetic. Altering
the numeric classes is definitely a tempting thing though.
I have XML definitions of the source log file and the resulting
summary I want to get.
e.g.
a
<src>
...
<column id="sourceadjacentaddress">
<type>string</type>
</column>
<column id="destadjacentaddress">
<type>string</type>
</column>
...
</src>
<rslt>
...
<column id="link1">
<test exp="@src_sourceadjacentaddress == '00-D0-41-68-
CF-56' || @src_destadjacentaddress == '00-D0-41-68-CF-56'"> </test>
<value exp= "+= @src_d_tooctets+src_d_fromoctets"> </value>
<type>int</type>
<scale exp="/@groupby_duration.megabyte"> </scale>
<format>%d</format>
</column>
...
</rslt>
This gets turned into ruby code that parses the log. It uses modified
column name as variables. The test expression determines if the
output column is modified, and the value expression is used to set or
alter the value. If the values start as nil, then adding a value,
will initialise them. Meeting further values, will result in them
being added on.
If multiple results are required (e.g. for a histogram), then a value
expression like
<value exp= "+= [@src_d_tooctets, @src_d_fromoctets]"> </value>
results in the to and from traffic being added to an array result
called @rslt_link1, rather than a simple numeric result.
I did this by I adding "each" and "each_with_index" to every Object,
thus allowing numbers and nil values to have an iterator.
I replaced the Fixnum + with one that would add arrays to numbers,
giving an array result or Fixnum result, depending on the value being
added.
Also the Arrays class was modified to add two arrays, by adding the
elements at the same array index to each other, not concatenating the
arrays.
I then committed the ultimate sin, and added a plus method to nil.
After all these hacks, I can
add a number to an array, and the first element will get altered.
add an array to a number, and get an Array with the first element
altered
add a number or Array to nil, and get that number or the Array
i.e.
class Object
def each
if self != nil then yield(self) end
end
def each_with_index
if self != nil then yield(self,0) end
end
def length
if self == nil then 0 else 1 end
end
end
class Array
def +(value)
value.each_with_index { |x,i| self[i] += x }
self
end
end
class Fixnum
alias oldPlus +
def +(value)
if(value.length == 1)
self.oldPlus(value)
else
value.+(self)
end
end
end
class NilClass
def +(value)
value
end
end
a = [1,3]
a += [5,2]
a.each {|b| puts b }
puts
a = 1
a += 2
a.each {|b| puts b }
puts
a += [5,2]
a.each {|b| puts b }
puts
a = nil
a += 10
a.each {|b| puts b }
puts
a = nil
a += [3,8]
a.each {|b| puts b }
puts
a = ["hello","I"]
a += [" world"," repent"]
a.each {|b| print b, " " }
puts
On 20/05/2006, at 2:18 PM, Sam Roberts wrote:
> Quoting rob / cs.auckland.ac.nz, on Sat, May 20, 2006 at 09:50:49AM
> +0900:
>> In the nil case, I wanted it to iterate and be printed as in the same
>> way as a non-nil value. In the plot data, a nil prints as '-'. I
>> hadn't thought of other code expecting to fail when the value was nil
>> or not an array. They probably wont want nil to have a to_s()
>> returning '-' either, not that anything has failed doing this, in
>> this instance.
>
> The temptation to change the core classes to work a little more
> like you
> want is almost overwhelming... at least I have found it so. I guess in
> this case you could do:
>
> def gnuplot_each(v, &proc)
> if v.respond_to? :each
> v.each &proc
> else
> yield v
> end
> end
>
> then instead of doing
>
> data.each {..}
>
> you could do
>
> gnuplot_each(data) {...}
>
>
> cheers,
> Sam
>
>