Returning with methods

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:
  > 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?

···

--
Posted via http://www.ruby-forum.com/.

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 Wright

···

On Jan 15, 2008, at 11:14 PM, Ryan Lewis wrote:

Now, why doesn't the inspect method return as an array?

Gary Wright 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 Wright

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

···

--
Posted via http://www.ruby-forum.com/\.

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