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
I'm not sure whether your approach will do what you want (if I understand you
correctly), for several reasons:
1) 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.
2) 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.
3) 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