Stefano Crocco
1/16/2008 8:46:00 AM
> 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