question about sub-class of array

  • Thread starter warren ferguson
  • Start date
W

warren ferguson

I don't understand why thsi isn't working. I wanted to introduce a subclass=
of the Array class called Bitvector. A bit vector is an array of 0s and 1s=
=2C ordered from lsb at index 0 to msb at the highest index=2C so
"10011" as a string would be [1=2C1=2C0=2C0=2C1] as an Bitvector. Here's wh=
at I tried:
=20
class Bitvector < Array
def initialize(*)
@a =3D super
end
def to_s
# convert Bitvector=2C ordered lsb to msb=2C
# to string of 0s and 1s=2C ordered msb to lsb
@a.map{|i| i.to_s(2)}.reverse.join
end
end
class String
def to_bv
# convert bit string of 0s and 1s=2C ordered msb to lsb=2C
# to Bitvector=2C ordered lsb to msb
Bitvector.new(self.reverse.split(//)).map{|k| k.to_i(2)}
end
end
# ----------------------------
v =3D "10011".to_bv
puts "v.class =3D #{v .class}"
puts "v =3D #{v}"
puts "--"
=20
v =3D Bitvector.new([0=2C1])
puts "v.class =3D #{v .class}"
puts "v =3D #{v}"
=20
The output from this program is
=20
v.class =3D Array
v =3D [1=2C 1=2C 0=2C 0=2C 1]
--
v.class =3D Bitvector
v =3D 10

What I don't understand is why the first part reports v is of class Array=
=2C instead of class Bitvector.
=20
Thanks=2C Warren =
 
D

David A. Black

Hi --

I don't understand why thsi isn't working. I wanted to introduce a subclass of the Array class called Bitvector. A bit vector is an array of 0s and 1s, ordered from lsb at index 0 to msb at the highest index, so
"10011" as a string would be [1,1,0,0,1] as an Bitvector. Here's what I tried:

class Bitvector < Array
def initialize(*)
@a = super
end
def to_s
# convert Bitvector, ordered lsb to msb,
# to string of 0s and 1s, ordered msb to lsb
@a.map{|i| i.to_s(2)}.reverse.join
end
end
class String
def to_bv
# convert bit string of 0s and 1s, ordered msb to lsb,
# to Bitvector, ordered lsb to msb
Bitvector.new(self.reverse.split(//)).map{|k| k.to_i(2)}
end
end
# ----------------------------
v = "10011".to_bv
puts "v.class = #{v .class}"
puts "v = #{v}"
puts "--"

v = Bitvector.new([0,1])
puts "v.class = #{v .class}"
puts "v = #{v}"

The output from this program is

v.class = Array
v = [1, 1, 0, 0, 1]
--
v.class = Bitvector
v = 10

What I don't understand is why the first part reports v is of class Array, instead of class Bitvector.

It's because of the map operation, which returns an Array.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com
 
W

Warren Ferguson

You're right, and I'm enjoying your book. Just to be clear, this solved
the problem, replace the earlier to_bv method with this

class String
def to_bv
# convert bit string of 0s and 1s, ordered msb to lsb,
# to Bitvector, ordered lsb to msb
v = self.reverse.split(//).map{|k| k.to_i(2)}
Bitvector.new(v)
end
end

So, I hope I understood your answer correctly. Thanks!
 
A

Aaron D. Gifford

Unrelated to your question, your code example made me curious:

class Bitvector < Array
def initialize(*)
@a = super
end
def to_s
# convert Bitvector, ordered lsb to msb,
# to string of 0s and 1s, ordered msb to lsb
@a.map{|i| i.to_s(2)}.reverse.join
end
end

Q: Is there any benefit to storing a copy of self in @a? Is there any
drawback to eliminating the initialize definition in the child class
and replacing the "@a" in the to_s method with "self"? What am I
missing?

Wondering,
Aaron out.
 
W

Warren Ferguson

Aaron said:
Q: Is there any benefit to storing a copy of self in @a? Is there any
drawback to eliminating the initialize definition in the child class
and replacing the "@a" in the to_s method with "self"? What am I
missing?

Wondering,
Aaron out.

No, there isn't, my bad. I added the initialize method because I thought
it might be the source of the original problem. Taking it out and using
self instead works fine.

I'm stil mystified why substituting the expression for v into
Bitvector.new(v) fails. Is it because Ruby optimizes that complex
expression by realizing the expression is of class Array and Bitvector
is a subclass of array?
 
D

David A. Black

Hi --

I'm stil mystified why substituting the expression for v into
Bitvector.new(v) fails. Is it because Ruby optimizes that complex
expression by realizing the expression is of class Array and Bitvector
is a subclass of array?

No; it's because you weren't doing what you think you were doing :)

Here are the two versions:

Bitvector.new(self.reverse.split(//)).map{|k| k.to_i(2)}

v = self.reverse.split(//).map{|k| k.to_i(2)}
Bitvector.new(v)

In the first one, you're calling map on a Bitvector object. In essence
it's this:

bv = Bitvector.new(self.reverse.split(//))
return bv.map{|k| k.to_i(2)}

In the second one, you're doing the map operation first, and then
sending the result of that operation to the BV initializer.

Move the parentheses around in the first one and you'll see what I mean:

Bitvector.new(self.reverse.split(//).map{|k| k.to_i(2)})


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com
 
W

Warren Ferguson

Give me a dope slap.
I never saw the incorrect closing paren :)
I must have added it, in the incorrect position,
when the parser complained.

Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top