[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Module Global Hash

Ryan Lewis

1/28/2008 5:06:00 AM

#!/usr/bin/env ruby
module Users
class User < Struct.new(:screenname, :password, :dob, :join_date,
:age)
def initialize(sn, pw, dob)
self.screenname = sn
self.password = pw
self.dob = Time.parse(dob)
self.join_date = Time.now
self.age = Time.now.year - Time.parse(dob).year
end
end
#########################################
user_hash = {}

def new(sn, pw, dob)
Users::user_hash[sn] = User.new(sn, pw, dob)
end
#########################################
module_function :new
end

I'm trying to make it so when I call:
Users::new("screenname", "pass", "1/15/91")

it adds a new instance of the User class into user_hash, but when I
execute the above code in IRB I get a NoMethodError for user_hash for
the Users:module

I've also tried putting both a @ and @@ infront of user_hash but irb
comes up with the same error.
--
Posted via http://www.ruby-....

8 Answers

Wyatt Greene

1/28/2008 5:17:00 AM

0

On Jan 28, 12:06 am, Ryan Lewis <c00lry...@gmail.com> wrote:
> #!/usr/bin/env ruby
> module Users
> class User < Struct.new(:screenname, :password, :dob, :join_date,
> :age)
> def initialize(sn, pw, dob)
> self.screenname = sn
> self.password = pw
> self.dob = Time.parse(dob)
> self.join_date = Time.now
> self.age = Time.now.year - Time.parse(dob).year
> end
> end
> #########################################
> user_hash = {}
>
> def new(sn, pw, dob)
> Users::user_hash[sn] = User.new(sn, pw, dob)
> end
> #########################################
> module_function :new
> end
>
> I'm trying to make it so when I call:
> Users::new("screenname", "pass", "1/15/91")
>
> it adds a new instance of the User class into user_hash, but when I
> execute the above code in IRB I get a NoMethodError for user_hash for
> the Users:module
>
> I've also tried putting both a @ and @@ infront of user_hash but irb
> comes up with the same error.
> --
> Posted viahttp://www.ruby-....

Remember that in Ruby, everything is an object and objects communicate
by passing messages (calling methods). So you can't get to variables
of an object (such as user_hash). You can only call methods that an
object responds to.

Wyatt Greene

1/28/2008 5:24:00 AM

0

On Jan 28, 12:17 am, Wyatt Greene <green...@yahoo.com> wrote:
> On Jan 28, 12:06 am, Ryan Lewis <c00lry...@gmail.com> wrote:
>
>
>
> > #!/usr/bin/env ruby
> > module Users
> > class User < Struct.new(:screenname, :password, :dob, :join_date,
> > :age)
> > def initialize(sn, pw, dob)
> > self.screenname = sn
> > self.password = pw
> > self.dob = Time.parse(dob)
> > self.join_date = Time.now
> > self.age = Time.now.year - Time.parse(dob).year
> > end
> > end
> > #########################################
> > user_hash = {}
>
> > def new(sn, pw, dob)
> > Users::user_hash[sn] = User.new(sn, pw, dob)
> > end
> > #########################################
> > module_function :new
> > end
>
> > I'm trying to make it so when I call:
> > Users::new("screenname", "pass", "1/15/91")
>
> > it adds a new instance of the User class into user_hash, but when I
> > execute the above code in IRB I get a NoMethodError for user_hash for
> > the Users:module
>
> > I've also tried putting both a @ and @@ infront of user_hash but irb
> > comes up with the same error.
> > --
> > Posted viahttp://www.ruby-....
>
> Remember that in Ruby, everything is an object and objects communicate
> by passing messages (calling methods). So you can't get to variables
> of an object (such as user_hash). You can only call methods that an
> object responds to.

I think what's going on here is that when the parser gets to the line
that says

user_hash = {}

it looks for a method called user_hash to execute. It doesn't realize
that you're trying to instantiate a variable. Maybe you should
consider turning the Users module into a class and trying @@user_hash
= {} again.

Ryan Lewis

1/28/2008 5:36:00 AM

0

Wyatt Greene wrote:
> On Jan 28, 12:17 am, Wyatt Greene <green...@yahoo.com> wrote:
>> > self.password = pw
>> > end
>>
>> > I've also tried putting both a @ and @@ infront of user_hash but irb
>> > comes up with the same error.
>> > --
>> > Posted viahttp://www.ruby-....
>>
>> Remember that in Ruby, everything is an object and objects communicate
>> by passing messages (calling methods). So you can't get to variables
>> of an object (such as user_hash). You can only call methods that an
>> object responds to.
>
> I think what's going on here is that when the parser gets to the line
> that says
>
> user_hash = {}
>
> it looks for a method called user_hash to execute. It doesn't realize
> that you're trying to instantiate a variable. Maybe you should
> consider turning the Users module into a class and trying @@user_hash
> = {} again.

I thought of this, but I'm going to be using a system with many many
users and each time I would call Users, I would crate two classes,
taking up twice as much memory.

Should I just drop the module and just keep it in a Users.rb file to
call it later?
--
Posted via http://www.ruby-....

Gary Wright

1/28/2008 5:57:00 AM

0


On Jan 28, 2008, at 12:06 AM, Ryan Lewis wrote:

> #!/usr/bin/env ruby
> module Users
> class User < Struct.new(:screenname, :password, :dob, :join_date,
> :age)
> def initialize(sn, pw, dob)
> self.screenname = sn
> self.password = pw
> self.dob = Time.parse(dob)
> self.join_date = Time.now
> self.age = Time.now.year - Time.parse(dob).year
> end
> end
> #########################################
> user_hash = {}
>
> def new(sn, pw, dob)
> Users::user_hash[sn] = User.new(sn, pw, dob)
> end
> #########################################
> module_function :new
> end
>
> I'm trying to make it so when I call:
> Users::new("screenname", "pass", "1/15/91")
>
> it adds a new instance of the User class into user_hash, but when I
> execute the above code in IRB I get a NoMethodError for user_hash for
> the Users:module

The way you've used it, user_hash is a local variable for the module
Users block. It disappears when the block ends.

You don't need a separate enclosing module. You've already got User.

In the following code, I used an instance variable of User,
@user_hash, to store the instances by name, User#initialize adds the
entry, and for added ease of use, I defined User.[] and User.[]= as a
way to access @user_hash.

require 'time'
class User < Struct.new(:screenname, :password, :dob, :join_date, :age)

class <<self
def [](u)
user_hash[u]
end
def []=(name, struct)
user_hash[name] = struct
end
def user_hash
@user_hash ||= {}
end
end

def initialize(sn, pw, dob)
self.screenname = sn
self.password = pw
self.dob = Time.parse(dob)
self.join_date = Time.now
self.age = Time.now.year - Time.parse(dob).year
self.class[sn] = self
end
end

User.new('bob', 'pw', '1/1/01')

p User['bob']
p User.user_hash


Ryan Lewis

1/28/2008 6:10:00 AM

0

Gary Wright wrote:
> class <<self

Hey, thanks man. I was thinking about defining [] and []=, but I didnt
know about <<self.


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

Robert Klemme

1/28/2008 10:18:00 AM

0

2008/1/28, Gary Wright <gwtmp01@mac.com>:
>
> On Jan 28, 2008, at 12:06 AM, Ryan Lewis wrote:
>
> > #!/usr/bin/env ruby
> > module Users
> > class User < Struct.new(:screenname, :password, :dob, :join_date,
> > :age)

You do not need to inherit from the new struct class, instead you can do

User = Struct.new(:screenname, :password, :dob, :join_date, :age)
class User
...
end

> > def initialize(sn, pw, dob)
> > self.screenname = sn
> > self.password = pw
> > self.dob = Time.parse(dob)
> > self.join_date = Time.now
> > self.age = Time.now.year - Time.parse(dob).year
> > end
> > end
> > #########################################
> > user_hash = {}
> >
> > def new(sn, pw, dob)
> > Users::user_hash[sn] = User.new(sn, pw, dob)
> > end
> > #########################################
> > module_function :new
> > end
> >
> > I'm trying to make it so when I call:
> > Users::new("screenname", "pass", "1/15/91")
> >
> > it adds a new instance of the User class into user_hash, but when I
> > execute the above code in IRB I get a NoMethodError for user_hash for
> > the Users:module

Note though that this approach will prevent any User instance from
being garbage collected. This might or might not be what you want. I
do not know the use case but there is another option: you can traverse
all User instances via ObjectSpace.

Ah, and another remark: the implementations show so far will also
allow to create two users with the same name but only one of them will
be accessible via the Hash.

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

James Gray

1/28/2008 1:22:00 PM

0

On Jan 28, 2008, at 4:18 AM, Robert Klemme wrote:

> 2008/1/28, Gary Wright <gwtmp01@mac.com>:
>>
>> On Jan 28, 2008, at 12:06 AM, Ryan Lewis wrote:
>>
>>> #!/usr/bin/env ruby
>>> module Users
>>> class User < Struct.new(:screenname, :password, :dob, :join_date,
>>> :age)
>
> You do not need to inherit from the new struct class, instead you =20
> can do
>
> User =3D Struct.new(:screenname, :password, :dob, :join_date, :age)
> class User
> ...
> end
>>

I like:

User =3D Struct.new(=85) do

end

James Edward Gray II=

Robert Klemme

1/28/2008 1:54:00 PM

0

2008/1/28, James Gray <james@grayproductions.net>:
> On Jan 28, 2008, at 4:18 AM, Robert Klemme wrote:
>
> > 2008/1/28, Gary Wright <gwtmp01@mac.com>:
> >>
> >> On Jan 28, 2008, at 12:06 AM, Ryan Lewis wrote:
> >>
> >>> #!/usr/bin/env ruby
> >>> module Users
> >>> class User < Struct.new(:screenname, :password, :dob, :join_date,
> >>> :age)
> >
> > You do not need to inherit from the new struct class, instead you
> > can do
> >
> > User =3D Struct.new(:screenname, :password, :dob, :join_date, :age)
> > class User
> > ...
> > end
> >>
>
> I like:
>
> User =3D Struct.new(=85) do

Of course. Unfortunately it does not work with class constants
properly. I should have mentioned that. (In my experiments I wanted
to use User::USERS.)

Thanks for pointing it out!

Kind regards

robert

--=20
use.inject do |as, often| as.you_can - without end