Referring to instance vars in a Struct?

I have a Struct – then I extend the class by adding some methods. I
expected to be able to access the instance vars, but it seems I can’t:

D:\temp\rubytest>more struct.rb
TestMe = Struct.new(‘TestMe’, :hey)

class TestMe
def show_hey
puts @hey
end
end

test = TestMe.new(‘hey’)
p test.hey
test.show_hey

D:\temp\rubytest>struct
"hey"
nil

D:\temp\rubytest>ruby -v
ruby 1.6.6 (2001-12-26) [i586-mswin32]

How can I reference the instance vars from inside the class created by
Struct.new?

Chris
http://clabs.org

class TestMe
def show_hey
puts @hey
end
end

Ah, well – change above to this:

class TestMe
def show_hey
puts hey
end
end

… and it works fine. Still, I’d expect to be able to use @hey.

Chris

Hi Chris,

I am not pretty sure, but by drawing analogy between C++ struct and class,
I think if you want to add method, it is probably more conventional to
use a class instead of a struct. Is there any reason why you don’t want
to create a TestMe class instead of a TestMe struct? Probably just the
amount of typing? Or for efficiency reason, do you think?

Regards,

Bill

···

===========================================================================
Chris Morris chrismo@clabs.org wrote:

class TestMe
def show_hey
puts @hey
end
end

Ah, well – change above to this:

class TestMe
def show_hey
puts hey
end
end

… and it works fine. Still, I’d expect to be able to use @hey.

Chris

Is there any reason why you don’t want
to create a TestMe class instead of a TestMe struct? Probably just the
amount of typing? Or for efficiency reason, do you think?

In my real code, I had a struct that represented a database row with several
fields. I know it’s not much more work (esp. with a good editor) to go from
this:

MyClass = Struct.new(‘MyClass’, :field1, :field2, …, :fieldx)

to this:

class MyClass
attr_accessor :field1, :field2, …, :fieldx

def initialize(field1, field2, ..., fieldx)
  @field1 = field1
  @field2 = field2
  ...
  @fieldx = fieldx
end

end

…but it is a bit more work.

But the point for me is still the surprise of not having an instance var
inside a Struct (although it does make sense that this is probably pushing
Structs beyond their intended use).

Chris

Hi Chris,

I agree with you that it is probably pushing Structs too far. As I do not
know much about database, in my opinion probably it is better to rephrase
your question to the group in a more direct way, such as the best way to
store a database record in Ruby and adding a method for each record. If
you have a specific database, probably some Ruby dbi is already available,
which will make your job even easier.

Regards,

Bill

···

===========================================================================
Chris Morris chrismo@clabs.org wrote:

In my real code, I had a struct that represented a database row with several
fields. I know it’s not much more work (esp. with a good editor) to go from
this:

(deleted)

But the point for me is still the surprise of not having an instance var
inside a Struct (although it does make sense that this is probably pushing
Structs beyond their intended use).

Hi –

But the point for me is still the surprise of not having an instance var
inside a Struct (although it does make sense that this is probably pushing
Structs beyond their intended use).

One way to look at it: having methods that set and retrieve same-named
instance variables is one way of implementing object attributes, and
while it’s convenient (especially with the attr_xxx wrappers for
method creation), it’s not the only way.

So Structs are in the attribute business, but how they do it is not
part of the deal.

Of course, if you want to, you can always get under the hood:

(s = (S = Struct.new :thing) .new) .thing = 123

(I was shooting for a palindrome :slight_smile: Anyway…

class S
alias :oldthing :thing
def thing
puts “Intercepted attribute get”
oldthing
end
end

p s.thing
# => Intercepted attribute get
# 123

etc.

David

···

On Tue, 15 Oct 2002, Chris Morris wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

A cleaner way to do this is to derive the class from an anonymous struct.

class S < Struct.new :thing
def thing
puts “Intercepted…”
super()
end
end

s = S.new
s.thing = 123
p s.thing
# => Intercepted…
# 123

···

On Tue, Oct 15, 2002 at 06:51:31AM +0900, dblack@candle.superlink.net wrote:

(s = (S = Struct.new :thing) .new) .thing = 123

(I was shooting for a palindrome :slight_smile: Anyway…

class S
alias :oldthing :thing
def thing
puts “Intercepted attribute get”
oldthing
end
end

p s.thing
# => Intercepted attribute get
# 123


Alan Chen
Digikata LLC
http://digikata.com