Jeff
Jeff

Reputation: 4003

ruby setting variable versus using variable

I'm somewhat new to ruby so there may be an easy solution to this.

But basically I want to reuse an object @result, so that when I execute a method on it (filter) I continue to be using the original object. However, as I run the method, the object itself seems to be changing.

The object (@result) is RDF::Query::Solutions class http://rdf.rubyforge.org/RDF/Query/Solutions.html#filter-instance_method

@result = rdf_query(query) # solutions object 

At this point the @result contains all the solutions, approximately 30 results

@pubinfo = @result.filter(:ptype => RDF::URI("http://scta.info/pubInfo"))

At this point @result becomes equivalent to what I want only @pubinfo to be. There are only 5 or so results

@contentinfo = @result.filter(:ptype => RDF::URI("http://scta.info/contentInfo"))

at this point @contentinfo comes up nil because the filter is actually on the solutions left from the previous filter. But i wanted to run this filter on the original contents of @result

@linkinginfo = @result.filter(:ptype => RDF::URI("http://scta.info/linkingInfo"))

Again predictable the @linking is 'nil' because @result was set to nil in the previous filter. But I don't want @result changing.

Please help.

update

Look what happens if i try the following

@pubinfo = @result
@pubinfo2 = @pubinfo.filter(:ptype => RDF::URI("http://scta.info/pubInfo"))
binding.pry

At this point @result = has been filtered. Why should should @result be affected at all by what I do to @pubinfo. In other words, how do i make @pubinfo a mere copy or duplicate of @result so that one is not affected by the other??

Upvotes: 0

Views: 48

Answers (1)

Uri Agassi
Uri Agassi

Reputation: 37409

If you read the documentation:

This method returns an undefined value.

Filters this solution sequence by the given criteria.

This is quite vague, I agree, but one thing stands out - it returns an undefined value, from this I conclude that this is a destructive method, which changes the current object rather than returns a new object with the result of the filter. Another hint to this is that it is Also known as: filter!, since methods ending in ! are by convention destructive in ruby.

Looking at the source code verified this conclusion, as it uses reject! in the code.

As to solutions on how to do it properly - I'm not familiar with this library, and it has proven quite hard to try and figure it out from the documentation, I suggest you find a way to do one of the following (ordered from most recommended, down to last fallback):

  1. Find a non-destructive API
  2. Find a dup or clone API
  3. Re-query before each filter...

And maybe try to contact the author to provide his own recommendation...

Upvotes: 1

Related Questions