struct.rb:
#!/usr/bin/env ruby
class User < Struct.new(:screenname, :password)
def initialize(sn, pw)
self.screenname = sn
self.password = pw
end
def inspect
self.values
end
end
in IRB:
Ruby> irb -r struct.rb
irb(main):001:0> myusr = User.new “c00lryguy”, “pass”
=> c00lryguypass #Returns as an array as a string
irb(main):002:0> myusr.values
=> [“c00lryguy”, “pass”] #Returns as an array
irb(main):003:0> myusr
=> c00lryguypass #Again, returns as an array as a string
Now, why doesn’t the inspect method return as an array?
On Jan 15, 2008, at 11:14 PM, Ryan L. wrote:
Now, why doesn’t the inspect method return as an array?
It does. Try
myusr.inspect.class
The problem is that IRB has to write that object to stdout so
Array#to_s gets called on the array returned by inspect.
It is probably a bad idea to break the convention that inspect
returns a string.
Gary W.
Gary W. wrote:
It does. Try
myusr.inspect.class
The problem is that IRB has to write that object to stdout so
Array#to_s gets called on the array returned by inspect.
It is probably a bad idea to break the convention that inspect
returns a string.
Gary W.
Well, what I’m basically trying to figure out is how to change the a
class into another class. Heres my new struct.rb:
#!/usr/bin/env ruby
class Hash
def to_struct(struct_name)
Struct.new(struct_name,*keys).new(*values)
end
end
class User
def initialize(sn, pw, dob)
vars = {:screenname => sn,
:password => pw,
:dob => Time.parse(dob),
:join_date => Time.now,
:age => Time.now.year - Time.parse(dob).year}
return vars.to_struct(“User”)
end
end
Now when I call User.new, I want it to turn the User class into the
‘vars’ Structure
def initialize(sn, pw, dob)
Now when I call User.new, I want it to turn the User class into the
‘vars’ Structure
I’m not sure whether your approach will do what you want (if I
understand you
correctly), for several reasons:
- your to_struct method will attempt to create a new class called
struct_name
every time it is called. This will produce a warning about redefining a
constant if it is called more than once with the same parameter.
- the to_struct method will return an instance of class Struct::User
(the
name of the class is struct_name), which is just another class, only
with the
[] method added.
- the return value of the initialize method is always ignored. If you
wanted
User.new to return the value returned by User#initialize, you need to
redefine User.new. If you do, though, you won’t be able to access the
new
user object. Look at this:
class C
def C.new(var)
obj = allocate
return obj.send(:initialize, var) #initialize is private
end
def initialize var
@var = var
@var * 2
end
end
c = C.new(3)
puts c
=> 6
Now, you have no variable containing the instance of C you just created.
I think you can use an OpenStruct instead of a Struct. OpenStruct is
like a
hash, but you can access items using method notation. Since OpenStruct
can be
initialized with a hash, you can define your to_struct method like this:
require ‘ostruct’
class Hash
def to_struct
OpenStruct.new self
end
end
If you truly need to use a Struct, you should first check whether a
class with
that name is already defined, and create it only if it isn’t. For
instance:
class Hash
def to_struct name
cls = Struct.const_get(name) rescue Struct.new( name, *keys)
cls.new *values
end
end
I hope this helps
Stefano