[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Can I access or find a object from it's instance variable?

Aki Wakabayashi

3/8/2009 2:55:00 AM

Hello.

Absolute newb here, and my very first post, so please bear with me...I
would like to be able to access an object with it's instance variable. I
simplified my example, but for instance:


class Foo
attr_accessor :some_id
end


one = Foo.new('7a')
two = Foo.new('2t')
three = Foo.new('33')


Is it possible to use the instance variable @some_id to access the
object itself? I was thinking of creating a class method for class Foo
such as:

class Foo
attr_accessor :some_id

self.find(some_id)
# somehow get an array of all the Foo objects, and iterate through
their
# some_id attributes until a match(s) is found, return the object(s)
end
end

...so I can do something like Foo.find('7a43') to access the object
'one'.

I am exhausted from searching how to get an array or hash of objects of
a given class, and I think I'm going in the wrong direction. Any
pointers will be greatly appreciated.


Thank you in advance :)
--
Posted via http://www.ruby-....

13 Answers

Aki Wakabayashi

3/8/2009 2:59:00 AM

0

Aki Wakabayashi wrote:

> ...so I can do something like Foo.find('7a43') to access the object
> 'one'.

I meant to say " Foo.find('7a') ", not "Foo.find('7a43')".

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

Sean O'Halpin

3/8/2009 4:08:00 AM

0

On Sun, Mar 8, 2009 at 2:55 AM, Aki Wakabayashi <zzyzx2001@gmail.com> wrote=
:
> Hello.
>
> Absolute newb here, and my very first post, so please bear with me...I
> would like to be able to access an object with it's instance variable. I
> simplified my example, but for instance:
>
>
> class Foo
> =A0attr_accessor :some_id
> end
>
>
> one =3D Foo.new('7a')
> two =3D Foo.new('2t')
> three =3D Foo.new('33')
>
>
> Is it possible to use the instance variable @some_id to access the
> object itself? I was thinking of creating a class method for class Foo
> such as:
>
> class Foo
> =A0attr_accessor :some_id
>
> =A0self.find(some_id)
> =A0 =A0# somehow get an array of all the Foo objects, and iterate through
> their
> =A0 =A0# some_id attributes until a match(s) is found, return the object(=
s)
> =A0end
> end
>
> ...so I can do something like Foo.find('7a43') to access the object
> 'one'.
>
> I am exhausted from searching how to get an array or hash of objects of
> a given class, and I think I'm going in the wrong direction. Any
> pointers will be greatly appreciated.
>
>
> Thank you in advance :)

Here's one way (not terribly efficient):

class Foo
attr_accessor :oid
def initialize(oid)
@oid =3D oid
end

def self.find(oid)
found =3D nil
ObjectSpace.each_object(self) do |o|
if o.oid =3D=3D oid
found =3D o
break
end
end
found
end
end

one =3D Foo.new('7a')
two =3D Foo.new('2t')
three =3D Foo.new('33')

Foo.find('7a') # =3D> #<Foo:0x244c8 @oid=3D"7a">

Regards,
Sean

Ian Trudel

3/8/2009 4:09:00 AM

0

Aki Wakabayashi wrote:
> Aki Wakabayashi wrote:
>
>> ...so I can do something like Foo.find('7a43') to access the object
>> 'one'.
>
> I meant to say " Foo.find('7a') ", not "Foo.find('7a43')".

Be inspired!
http://www.juixe.com/techknow/index.php/2007/01/22/ruby-class...
--
Posted via http://www.ruby-....

Aki Wakabayashi

3/8/2009 4:57:00 AM

0

Thank you Ian, and Sean.

I'm surprised that I got a reply so quickly! I was just reading p404 of
the Pickaxe book(1.8) and reading about ObjectSpace, but it was really
brief, and I was reading it over and over until I started to begin
talking to myself (not good).

What I really wanted was to get the actual identifier of the object, but
for now I'll create a instance variable for the actual identifier so I
can put it in the to_s method, and I can get things working.

I know it's not the Rubyist way, but I just started, so hopefully I can
find a better way later and post it here.

Once again, thank you guys. You were very supportive, and I would have
not figured this out so painlessly without your help.


Aki


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

Christopher Dicely

3/8/2009 8:52:00 AM

0

On Sat, Mar 7, 2009 at 6:55 PM, Aki Wakabayashi <zzyzx2001@gmail.com> wrote=
:
> Hello.
>
> Absolute newb here, and my very first post, so please bear with me...I
> would like to be able to access an object with it's instance variable. I
> simplified my example, but for instance:
>
>
> class Foo
> =C2=A0attr_accessor :some_id
> end
>
>
> one =3D Foo.new('7a')
> two =3D Foo.new('2t')
> three =3D Foo.new('33')
>
>
> Is it possible to use the instance variable @some_id to access the
> object itself? I was thinking of creating a class method for class Foo
> such as:
>
> class Foo
> =C2=A0attr_accessor :some_id
>
> =C2=A0self.find(some_id)
> =C2=A0 =C2=A0# somehow get an array of all the Foo objects, and iterate t=
hrough
> their
> =C2=A0 =C2=A0# some_id attributes until a match(s) is found, return the o=
bject(s)
> =C2=A0end
> end
>
> ...so I can do something like Foo.find('7a43') to access the object
> 'one'.
>
> I am exhausted from searching how to get an array or hash of objects of
> a given class, and I think I'm going in the wrong direction. Any
> pointers will be greatly appreciated.
>
>
> Thank you in advance :)
> --
> Posted via http://www.ruby-....

Others have posted ways using ObjectSpace, which works; its always
seemed to me though that if you know you are going to need to do
something like that with objects of a particular class, that it may
often make more sense to do something like this:

class Foo
attr_reader :key

@@instances =3D Hash.new {|h,k| h[k] =3D []}

def self.find(key_val)
@@instances[key_val].first
end

def self.find_all(key_val)
@@instances[key_val].dup
end

def key=3D(new_key)
@@instances[@key].delete self
@@instances[new_key] << self
@key =3D new_key
end

def initialize(key_val)
@key =3D key_val
@@instances[key_val] << self
end
end

-lim-

3/8/2009 9:29:00 AM

0

> class Foo
> =A0 attr_reader :key
>
> =A0 @@instances =3D Hash.new {|h,k| h[k] =3D []}
> [...]
> =A0 def initialize(key_val)
> =A0 =A0 @key =3D key_val
> =A0 =A0 @@instances[key_val] << self
> =A0 end
> end

I don't know ruby well enough but I'd assume a weak reference would be
preferable -- unless the script won't run very long anyway.

In general, if you want control over the instances of a class, you
could also consider something singleton like:


require 'weakref'

class Foo
attr_reader :key
@instances =3D {}

def initialize(key)
@key =3D key
end

def self.instance(key)
find(key) || Foo.new(key).tap {|o| @instances[key] =3D
WeakRef.new(o)}
end

def self.find(key)
if @instances.has_key?(key) and @instances[key].weakref_alive?
@instances[key].__getobj__
end
end
end

a =3D Foo.instance("a")
a1 =3D Foo.instance("a")
a2 =3D Foo.find("a")
p a.object_id, a1.object_id, a2.object_id

Christopher Dicely

3/8/2009 9:47:00 AM

0

On Sun, Mar 8, 2009 at 1:29 AM, Leo <minilith@gmail.com> wrote:
>> class Foo
>> =C2=A0 attr_reader :key
>>
>> =C2=A0 @@instances =3D Hash.new {|h,k| h[k] =3D []}
>> [...]
>> =C2=A0 def initialize(key_val)
>> =C2=A0 =C2=A0 @key =3D key_val
>> =C2=A0 =C2=A0 @@instances[key_val] << self
>> =C2=A0 end
>> end
>
> I don't know ruby well enough but I'd assume a weak reference would be
> preferable -- unless the script won't run very long anyway.

Yeah, in most real-world cases using this basic design, you're
probably going to want to either use weak references (and add code to
manage them so that dead references are silently cleaned up rather
than throwing exceptions, or provide an explicit ability to delete an
instance from the class-level index, depending on how you expect
objects of the class to be used.

F. Senault

3/8/2009 10:18:00 AM

0

Le 8 mars 2009 à 03:55, Aki Wakabayashi a écrit :

> Hello.
>
> Absolute newb here, and my very first post, so please bear with me...I
> would like to be able to access an object with it's instance variable. I
> simplified my example, but for instance:

I've have to solve the same problem some time ago, here's how I've done
it (with a small example) :

http://pastie....

(In the original problem, I used the cache system to enable the use of
object instances, ids or keys indifferently in method calls.)

Fred
--
The me that you know doesn't come around much (Nine inch Nails,
That part of me isn't here anymore The Becoming)
All pain disappears it's the nature of my circuitry
Drowns out all I hear there's no escape from this my new consciousness

Robert Klemme

3/8/2009 1:26:00 PM

0

On 08.03.2009 05:57, Aki Wakabayashi wrote:
> What I really wanted was to get the actual identifier of the object, but

What exactly do you mean by "actual identifier"? If you mean #object_id
then there is method ObjectSpace._id2ref.

http://www.ruby-doc.org/core/classes/ObjectSpace.ht...

> for now I'll create a instance variable for the actual identifier so I
> can put it in the to_s method, and I can get things working.

If you mean the object id then you do not need an instance variable to
put it into to_s's output.

> I know it's not the Rubyist way, but I just started, so hopefully I can
> find a better way later and post it here.

The question is: what are you trying to achieve?

Kind regards

robert

Aki Wakabayashi

3/8/2009 4:32:00 PM

0

Thank you everyone. I would like thank every one one by one, but I think
that will make this place look like a blog and I'm not sure if that's
proper to this forum. But I really appreciate everyone's support.

Creating a class variable, or using weak references (though still
complicated to me) made very much sense. The code at
http://pastie.... was clear to the point where a @name instance
variable is added to the class.

After cramming all this code into by head, I started to wonder if I was
able to do what I wanted to by using the #object_id? I'm not sure at
this point. Below is an example of what I wanted to achieve.

> What exactly do you mean by "actual identifier"? If you mean #object_id
> then there is method ObjectSpace._id2ref.

I meant the variable that I used to point to the object, when they are
created like:

var = Foo.new(77)

I wanted to get access to 'var' by using it's @some_id which is 77.

> The question is: what are you trying to achieve?

Thank you for asking. I was wondering how to update relations(imagine a
social networking site) between objects of a single Class. I hope this
will clarify why I want to access the variable of the object with its
instance variable. This how far I got last night:

class Foo

attr_accessor :name, :some_id, :relations

def self.update_relationship(foo1, foo2)
# code that adds @relations for foo1, and foo2 and updates it with
# it's own MINUS its own :some_id, and updates other @some_id's
included
# in foo1.relations + foo2.relations.
end

def self.find_by_some_id(some_id)
found = nil
ObjectSpace.each_object(Foo) { |o| found = o if o.oid == oid}
found
end

def to_s
@name
end

end


(create two objects):

John = Foo.new('John', 1,[])
Dave = Foo.new('Dave', 2,[])

(create a relationship between the two):

Foo.update_relationship(John, Dave)

John.relations -> [2]
Dave.relations -> [1]


Let's assume that along the line more objects are created and a new
relationship is created with John.(I'm just going to create a new object
and populate it's @relations instance variable, so the variables are
visible)

Steve = Foo.new('Steve', 104, [55, 77])

Foo.update_relationship(Steve, John)

John.relations -> [2, 55, 77, 104]
Steve.relations -> [1,2,55,77]

...well, that's good, but all the other objects (with @some_id 2, 55 and
77) would have to be updated right? For starters, Dave, the second
object (with @some_id = 2) is currently still:

Dave.relations -> [1]

Where it has to be updated to [1, 55, 77, 104]

So in order to access the Dave object, I only had 2, it's @some_id
instance variable to access it. Now, since I included the variable name
in the instance variable I can access the Dave object with the
find_by_some_id class method, and
get the @name instance variable which is the same as the variable (THIS
IS WHERE I THOUGHT IT WAS NOT A RUBYIST SOLUTION)

I'm going to read a little more and see if I can use the object's
#object_id to do all of this.

Thank you.

Aki


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