Simple iteration in a function problem

i’m trying to do this, and I’m stuck

class holderOfYs

def initialize()
@ys = Array.new
end

def addX( x )
@ys << x
end

this is the problem function. all I want is the specific (ONE)

element

from the @ys array that matches the id, but when you iterate over the

array, i can’t find a way to only have one element returned

def getXById(id)
@ys.each_with_index do |comp, index|
if( @ys[index].getUniqueId == id )
@ys.fetch(index)
end
end
end

class Y
@uniqueId

def getUniqueId
@uniqueId
end

end

class X < Y
def getUniqueId
super
end
end

I tried setting a variable like :
def getXById(id)
inst = X.new
@ys.each_with_index do |comp, index|
if( @ys[index].getUniqueId == id )
inst = @ys.fetch(index)
end
end

inst
end

…but I’m not looking to instantiate a new X, and even that solution
seems to screw up the @ys array.

Blake M. wrote:

this is the problem function. all I want is the specific (ONE)

element

from the @ys array that matches the id, but when you iterate over the

array, i can’t find a way to only have one element returned

def getXById(id)

Instead of:

@ys.each_with_index do |comp, index|
if( @ys[index].getUniqueId == id )
@ys.fetch(index)
end
end

try this:

@ys.find {|x| x.getUniqueId == id}

Blake M. wrote:

this is the problem function. all I want is the specific (ONE)

element

from the @ys array that matches the id, but when you iterate over the

array, i can’t find a way to only have one element returned

def getXById(id)
@ys.each_with_index do |comp, index|
if( @ys[index].getUniqueId == id )
@ys.fetch(index)
end
end
end

Perhaps

def getXById( id )
@ys.detect { |y| y.getUniqueId == id }
end

See the docs for Enumerable#detect about handling what’s returned if
nothing is found.

Mike F. wrote:

Blake M. wrote:

this is the problem function. all I want is the specific (ONE)

element

from the @ys array that matches the id, but when you iterate over the

array, i can’t find a way to only have one element returned

def getXById(id)
@ys.each_with_index do |comp, index|
if( @ys[index].getUniqueId == id )
@ys.fetch(index)
end
end
end

Perhaps

def getXById( id )
@ys.detect { |y| y.getUniqueId == id }
end

See the docs for Enumerable#detect about handling what’s returned if
nothing is found.

I don’t know where “detect” comes from (@ys is an array, and it doesn’t
seem to be a method of Array)? however, I tried that and the result is
null, but I know for certain that the id being searched for does match
an element in the @ys array (because I wrote a function to print out the
ids in @ys)

On Dec 1, 2006, at 12:57 PM, Blake M. wrote:

i’m trying to do this, and I’m stuck

I’ve tried to answer your question and Rubyify your code a bit:

class YHolder
def initialize
@ys = Array.new
end

def add_y(y)
@ys << y
end
alias_method :<<, :add_y

def fetch_by_id(id)
@ys.find { |y| y.object_id == id }
end
alias_method :[], :fetch_by_id
end

class Y; end
class X < Y; end

holder, ids = YHolder.new, Array.new
10.times do
new_y_or_x = [Y, X][rand(2)].new

ids << new_y_or_x.object_id
holder << new_y_or_x
end

p holder # show the collection

pick one by id

pick = ids[3]
p pick
p holder[pick]

>> #<YHolder:0x1e2928 @ys=[#<Y:0x1e289c>, #<X:0x1e2874>, #<X:

0x1e284c>,

>> #<Y:0x1e2824>, #<X:0x1e27fc>, #<Y:

0x1e27d4>,

>> #<Y:0x1e27ac>, #<X:0x1e2784>, #<X:

0x1e275c>,

>> #<Y:0x1e2734>]>

>> 988178

>> #<Y:0x1e2824>

END

Hope that helps.

James Edward G. II

pick one by id

pick = ids[3]
p pick
p holder[pick]

>> #<YHolder:0x1e2928 @ys=[#<Y:0x1e289c>, #<X:0x1e2874>, #<X:

0x1e284c>,

>> #<Y:0x1e2824>, #<X:0x1e27fc>, #<Y:

0x1e27d4>,

>> #<Y:0x1e27ac>, #<X:0x1e2784>, #<X:

0x1e275c>,

>> #<Y:0x1e2734>]>

>> 988178

>> #<Y:0x1e2824>

END

Hope that helps.

James Edward G. II

Note: The ids are strings. The @ys.find { |y| y.object_id == id } still
isn’t working for me, i also tried y.object_id.equals(id) but I can’t
seem to find the darn match : /

See the docs for Enumerable#detect about handling what’s returned if
nothing is found.

I don’t know where “detect” comes from (@ys is an array, and it doesn’t
seem to be a method of Array)? however, I tried that and the result is
null, but I know for certain that the id being searched for does match
an element in the @ys array (because I wrote a function to print out the
ids in @ys)

Sorry, missed that “Enumerable”

Blake M. wrote:

0x1e27d4>,
James Edward G. II

Note: The ids are strings. The @ys.find { |y| y.object_id == id } still
isn’t working for me, i also tried y.object_id.equals(id) but I can’t
seem to find the darn match : /

Please show us your code, and make it as simple as possible. Like this:


#!/usr/bin/ruby -w

b = “b”

b_id = b.object_id

ys = [ “a”,b,“c”,“d” ]

puts ys.find { |i| i.object_id == b_id } # => “b”

puts ys.find { |i| i.object_id == b } # => nil

puts ys.find { |i| i.object_id == “b” } # => nil


Notice in your version of the code that “id” must equal the object id,
not
the object.

I tried setting a variable like :
def getXById(id)
inst = X.new
@ys.each_with_index do |comp, index|
if( @ys[index].getUniqueId == id )
inst = @ys.fetch(index)
end
end

inst
end

…but I’m not looking to instantiate a new X, and even that solution
seems to screw up the @ys array.

I’ve also tried this:
def getXById(id)
matchingIndx = 0
@components.each_index do |index|
if( @components[index].getUniqueId == uniqueId )
matchingIndx = index
end
end

@components.fetch(matchingIndx)

end

but it just returns the 0th one every time (I’m assuming there wasn’t a
match)

Please show us your code, and make it as simple as possible. Like this:

class Widget

def initialize(title)
@components = Array.new
end

def add_component(component)
@components << component
end

def component(uniqueId) # note: uniqueId is a string
@components.find { |comp| comp.getUniqueId == uniqueId }
end
end

=========================================================
class SearchWidgetComponent
:attr_reader :uniqueId

def getUniqueId
@uniqueId
end
end

=============================
class SearchWidgetComparisonComponent

def getUniqueId
super
end
end

in my view index.rhtml, I have:
<% @sw.component(“swComparisonComp1”).some_func_call_on_swcc()… %>

I get an error " NoMethodError in Region#index" “You have a nil object
when you didn’t expect it!” in index.rhtml at the
.some_func_call_on_swcc() line

Blake M. wrote:

inst
matchingIndx = index
end
end

@components.fetch(matchingIndx)

end

but it just returns the 0th one every time (I’m assuming there wasn’t a
match)

You believe you are solving a specific programming problem, but in fact
you
are learning how to solve programming problems.

  1. Put in as many message-printing lines into your program as you need
    to
    find out what is going on.

  2. Keep adding debugging lines until the problem becomes obvious.

  3. Repeat as required.

When you look at a line of code like this:

@components.each_index do |index|

  if( @components[index].getUniqueId == uniqueId )
    matchingIndx = index
  end
end

And it doesn’t deliver, what should you do? You should add lines that
print
helpful messages until it is impossible not to see the problem.

First question. Is the ID in the array? Find out by printing all the
array’s
IDs and look at them. Is it there?

Second question. Does the variable “uniqueId” actually contain the
required
ID? Find out by printing its value. It is right?

Third question. Can the comparison you are using actually produce the
result
you seek? Find out by testing it with two variables that actually are
equal.

Most difficult programming problems are beaten to death in just this
way.
The important things to remember are (1) the computer is breathtakingly
dumb, (2) you are smarter than the computer, but (3) successful
debugging
requires you to think like the computer, as demeaning as that might seem
at
first.

I think perhaps the problem is how I’m comparing strings. What is the
proper way to compare two strings, like:

@str1 = “boo”

def meth(str)
if( @str1 == str )
end

meth(“boo”)

Is that the appropriate way to compare them?

Blake M. wrote:

@components << component
end

def component(uniqueId) # note: uniqueId is a string

What? “uniqueId” is string? It cannot be a string, it has to be an ID,
something gotten with “.object_id”, nothing else will do. And two
strings
with the same content do not necessarily have the same ID.

In your method “uniqueId”, you should be returning “self.object_id”.

In your code, I do not see where you acquire the “.object_id” of any
object.

Very basically, in order to solve a problem like this, you simply must
post
a short, terse, concise bit of code, that (1) can be run by a newsgroup
reader, and (2) shows the problem.

Posting bits and pieces of code, but never a short working example, is a
sure way to assure that this thread will go on forever.

Paul L. wrote:

Blake M. wrote:

@components << component
end

def component(uniqueId) # note: uniqueId is a string

What? “uniqueId” is string? It cannot be a string, it has to be an ID,
something gotten with “.object_id”, nothing else will do. And two
strings
with the same content do not necessarily have the same ID.

In your method “uniqueId”, you should be returning “self.object_id”.

In your code, I do not see where you acquire the “.object_id” of any
object.

Very basically, in order to solve a problem like this, you simply must
post
a short, terse, concise bit of code, that (1) can be run by a newsgroup
reader, and (2) shows the problem.

Posting bits and pieces of code, but never a short working example, is a
sure way to assure that this thread will go on forever.
Why can’t it be a string, I can use whatever I want to identify an
object. Now, if you’re saying it’s not possible to compare two strings,
then I’d see your point. I can’t make the code any simpler without
sacrificing understanding of what I’m trying to accomplish. It’s very
simple, each component has an id, a unique id, that I assign to it,
which is a string, and is unique (I’ll enforce that later). I have an
array of these components, and I want to search that array given a
string to find the matching component by id.

Hi –

On Sat, 2 Dec 2006, Blake M. wrote:

def component(uniqueId) # note: uniqueId is a string
@components.find { |comp| comp.getUniqueId == uniqueId }
end
end

=========================================================
class SearchWidgetComponent
:attr_reader :uniqueId

No : on attr_reader; it’s a method:

attr_reader :uniqueID

def getUniqueId
@uniqueId
end

You’ve now got two “get” methods for @uniqueID: the one attr_reader
created (which will be called uniqueID), and the one you’ve written.

end

=============================
class SearchWidgetComparisonComponent

def getUniqueId
super

super won’t work here, unless this class is a subclass of
SearchWidgetComponent. And if it is a subclass, it will have that
method anyway. And… you don’t need the method in the first place,
because of attr_reader :slight_smile:

end
end

Also, you need a way to set as well as get your uniqueID values,
unless they’re going to be something inherent in the object (the
object’s object_id). Do you want attr_writer too?

David

Hi –

On Sat, 2 Dec 2006, Blake M. wrote:

=========================================================

object’s object_id). Do you want attr_writer too?
@components = Array.new
@components.each_with_index do |comp, index|
==================================
class SearchWidgetComparisonComponent < SearchWidgetComponent
unique ids)
you didn’t expect it! The error occured while evaluating nil.stylize"

Thanks ahead for the help yo. I’ve been tearin my hair out for 5 hours
now.

I wish I could help. I can’t spot anything that would cause @obj to
be nil, and when I try a standalone version of your code (essentially
what you’ve got minus the ERB markup), it runs fine.

Is it possible you’ve got symbols in one place (maybe when you create
the components) and strings in another?

David

I wish I could help. I can’t spot anything that would cause @obj to
be nil, and when I try a standalone version of your code (essentially
what you’ve got minus the ERB markup), it runs fine.

Is it possible you’ve got symbols in one place (maybe when you create
the components) and strings in another?

David
David, thanks for the help. I did create a test.rb file and the code
worked, as you said, as it should, so there must be something else in
the code that is changing the ids. I think it’s time to start
commenting the heck out of everything till I find out where it is. I’ll
keep looking and post the solution when I find it (hopefully soon!).
Thanks.

unknown wrote:

Hi –

On Sat, 2 Dec 2006, Blake M. wrote:

=========================================================

object’s object_id). Do you want attr_writer too?
@components = Array.new
@components.each_with_index do |comp, index|
==================================
class SearchWidgetComparisonComponent < SearchWidgetComponent
unique ids)
you didn’t expect it! The error occured while evaluating nil.stylize"

Thanks ahead for the help yo. I’ve been tearin my hair out for 5 hours
now.

I wish I could help. I can’t spot anything that would cause @obj to
be nil, and when I try a standalone version of your code (essentially
what you’ve got minus the ERB markup), it runs fine.

Is it possible you’ve got symbols in one place (maybe when you create
the components) and strings in another?

David
Ah you guys are gonna kill me now. I feel I must break out the
vaseline(sp??) and prepare to be hung.

Well, it just so happens I was passing the wrong uniqueId to the
component() function in the .rhtml file. 6 hours
later…unbelievable…I’m sure I’ll be in this weekend making up the
time. The whole time I was reading “swCompareComp1” as
“swComparisonComp1”. Unbelievable. Well, thanks a bunch guys, and
sorry for filling up your inboxes. Have good mosh-pitting!

Blake M. wrote:

/ …

Posting bits and pieces of code, but never a short working example, is a
sure way to assure that this thread will go on forever.

Why can’t it be a string, I can use whatever I want to identify an
object.

  1. I can see why this thread goes on so long – instead of meeting my
    request, you just changed the subject.

  2. It should not be a string because your goal is to compare two object
    IDs,
    not strings. You are calling the variable “uniqueId”, don’t you think it
    should be what it says it is? BTW use the Rubyish “unique_id” rather
    than
    “uniqueId”.

Now, if you’re saying it’s not possible to compare two strings,
then I’d see your point.

It is possible to compare two strings, but your goal is to compare two
object IDs. Object IDs are not strings, and strings are not object IDs.

I can’t make the code any simpler without
sacrificing understanding of what I’m trying to accomplish. It’s very
simple, each component has an id, a unique id, that I assign to it,
which is a string,

Don’t use a string. Use the object ID provided by (object).object_id.
That
way, you won’t confuse everyone including yourself.

and is unique (I’ll enforce that later). I have an
array of these components, and I want to search that array given a
string to find the matching component by id.

And matching by ID rather than by string is faster, along with
everything
else.

On Dec 1, 2006, at 4:34 PM, Blake M. wrote:

Well, it just so happens I was passing the wrong uniqueId to the
component() function in the .rhtml file. 6 hours
later…unbelievable…

Now the key is to learn a lesson from this, right? Here’s my best
offer:

I can’t remember the last time I had a six hour debugging session
after I started unit testing. Maybe it’s time to add a new tool to
your belt…

James Edward G. II