The Thomas/Hunt book says 'update' is a method in Hash and CGI::Session, but
not in Array.
sorry - i meant Array#replace
def initialize(*args, &block)
Could (must?) be invoked as MyArrayType['x','y']{|i| dostuff(i)} so that
block(element) could be executed which in turn would invoke
dostuff(elemement) for selected elements in the array(s) in args.
~ > cat a.rb
class A
def initialize(*args, &block)
puts '---'
p "args <#{ args.inspect }>"
block.call if block
end
end
A.new
A.new{ p 'forty-two'}
A.new 42
A.new(42){ p 'forty-two'}
~ > ruby a.rb
---
"args <[]>"
---
"args <[]>"
"forty-two"
---
"args <[42]>"
---
"args <[42]>"
"forty-two"
if you look at the docs for Array#new you'll see it comes in three of the
flavors above, since i needed the same method signature as Array#new this was
a fast dirty way to do it without really needing to know the exact methed
signature. if you program C this is about like saying
int
method()
{
}
or in C++
int
method(...)
{
}
execpt it's __much__ easier to get at whatever args the methods has been
called with!
My guess is that this statement is equivalent to "if 'Array' is the type of
the first item in the 'args' array." That doesn't comport with "Programming
Ruby", Thomas et al, 2001, page 283, which seems to indicate "element by
element comparison of two arrays." But I can't see how you could intend to
compare Array's elements, because I don't think Array HAS any elements when
'initialize' is invoked.
note the '===' vs '=='. the method being invoked is the __class__ method
'==='. in this case Array inherits this method from Class - one of it's
parents. so check out the class method of Class named '==='. ;-)
eg.
~ > cat b.rb
array = [42]
hash = {4 => 2}
file = open __FILE__
[array, hash, file].each do |obj|
[Array, Hash, File].each do |klass|
printf "<%s> %s <%s>\n", obj.inspect, (klass === obj ? "is a" : "is not a"), klass
end
end
~ > ruby b.rb
<[42]> is a <Array>
<[42]> is not a <Hash>
<[42]> is not a <File>
<{4=>2}> is not a <Array>
<{4=>2}> is a <Hash>
<{4=>2}> is not a <File>
<#<File:b.rb>> is not a <Array>
<#<File:b.rb>> is not a <Hash>
<#<File:b.rb>> is a <File>
case uses '===' by default, so you can also
~ > cat c.rb
array = [42]
hash = {4 => 2}
file = open __FILE__
[array, hash, file].each do |obj|
case obj
when Array
puts "<#{ obj.inspect }> is a Array"
when Hash
puts "<#{ obj.inspect }> is a Hash"
when File
puts "<#{ obj.inspect }> is a File"
end
end
~ > ruby c.rb
<[42]> is a Array
<{4=>2}> is a Hash
<#<File:c.rb>> is a File
this is a bit more rubyish i think - but both peices of code are asking if an
object is of a certain __type__
Equivalent to "ary = args[0]" in this instance, since 'args' is not modified
(no "!" after "shift").
you can always play and find out:
~ > irb
irb(main):001:0> a = [0,1,2]
=> [0, 1, 2]
irb(main):002:0> a.shift
=> 0
irb(main):003:0> a
=> [1, 2]
shift is a method that DOES modify it's reciever. not all such methods end in
'!', such as Array#delete. there is no hard and fast rule about this in ruby,
but in general one can say that methods for which it is non-intuitive that the
method would modify the reciever have a bang, and methods for which there are
two versions (modifying and non-modifying) have a bang version. essentially
it's up to the designer of the class to decide which methods are 'dangerous'.
eg.
~ > irb
irb(main):001:0> a = [0,1,2]
=> [0, 1, 2]
irb(main):002:0> a.map{|elem| elem ** 2}
=> [0, 1, 4]
irb(main):003:0> a
=> [0, 1, 2]
irb(main):004:0> a.map!{|elem| elem ** 2}
=> [0, 1, 4]
irb(main):005:0> a
=> [0, 1, 4]
irb(main):006:0> a.delete 0
=> 0
irb(main):007:0> a
=> [1, 4]
Invokes Array#initialze with the original arguments that 'initialize' got,
but I don't see what this accomplishes.
that's sort of the point - who knows what Array#initialize does, but we are
trying to 'be an Array' so we had better do it. we could look into the
sources for Array and find out, or let ruby do it for us. consider:
~ > cat d.rb
class Base
def initialize val
@Val = val
end
def meth
p(
@Val + 2)
end
end
class Derived0 < Base
def initialize(*args, &block)
super
end
end
class Derived1 < Base
def initialize(*args, &block)
# nothing
end
end
d0 = Derived0.new 40
d1 = Derived1.new 40
d0.meth
d1.meth
~ > ruby d.rb
42
d.rb:7:in `meth': undefined method `+' for nil:NilClass (NoMethodError)
from d.rb:26
I assume you're talking about using a Module and including it into a class
or classes.
As before, I appreciate your tutoring.
well - don't take my word for it, play around and read the group - lot's of
way to skin a cat. ;-)
cheers.
-a
--
===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| URL ::
http://www.ngdc.noaa.gov/stp/
| TRY :: for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done
===============================================================================