Forum OpenACS Q&A: need some brilliant curmudgeons.

Collapse
Posted by Todd Gillespie on
Lately I've been writing ns_ruby, a nsd extension for Ruby evaluation. One thing has been troubling me: the damnable ns_set abstraction. It's erratic. It's weak. The API is god-awful.
That said, I don't see an obvious mapping to a nicer data structure. Here is where your nsd tcl complaints come to light. If you have previously found the 'right way' to represent the data that ns_set handles (HTTP headers, database query results, etc), I would love to hear it.

Oh, and come to the social on Monday. For great justice!

Collapse
Posted by mark dalrymple on
One weird thing that struck me when I was wallowing around inside of ns_set, was that it's not actually a set, just a quasi-associative array (but stored in a linear fashion) that can hold duplicate keys. This actually works out well for http headers since you can multiple of the same header.  Trying to map that behavior on to something saner usually degenerates you back to the current ns_set way.
Collapse
Posted by Tom Jackson on

The same discussion came up today in the AOLserver chat. You need to be able to handle duplicate keys in the order you find them. Database queries could return duplicate column names as well. If you are trying to come up with something useful, don't try to engineer a new structure for everyone to learn.

In reviewing the API today, I did notice one item I didn't really like. You can easily verify that you have more than one key with the same name. Getting the second one seems to require you to delete the first, if you try to access the key by name. Stepping through by index still gives you all the key/value pairs. It would be nice if you could specify a start index for your search for the next matching key. Other than this one problem, I think it will be difficult to improve the structure and function of an ns_set.

Collapse
Posted by Todd Gillespie on
But it's not even vaguely correct!! If you have a list of key-value pairs and keys are not unique, shouldn't the proper response to a key query be a list of pairs that match?? The ns_set functions just return the first value and quits. So we always have to write code to scan the ns_set and collect these other values -- in other words, the client program is writing the hash lookups. This is wrong!!

I'd like to think someone has a better structure than this.

If you are trying to come up with something useful, don't try to engineer a new structure for everyone to learn.
Maybe it's just the lateness of the hour, but this is the most inflammatory luddite view I've seen today. If I find a more useful structure, hell yes I'll make people learn it! What, did we decide to stop coding??
Collapse
Posted by Tom Jackson on

If it is a list, then what, you still have to write code to figure out if it is a list or not. I don't think there is a magic solution. It isn't even right to assume that a single key query should return all matches, because that destroys the order that you put them in. Ns_set preserves the order, which could be important.

I don't see how the stucture could be 'incorrect' it seems to be working fine, billions of database rows, and http headers have passed through it just fine. And now you are suddenly upset at it. I'm not a luddite, and neither were the authors of ns_set. They innovated a new data structure that works. If you discover a more useful structure, I will be one of the first to use it.

Collapse
Posted by David Walker on
The addition of "ns_set findall" and "ns_set ifindall" that returns
a list would seem to answer this complaint.  one could read "ns_set
unique" or "ns_set iunique" (these already exist) to determine if
the list contains more than one entry.
Collapse
Posted by Todd Gillespie on
Yes, Tom, I have run a few million rows through the ns_set structure. And as an extension programmer I admire its small footprint, I have never liked its interface to tcl programmers.

If it is a list, then what, you still have to write code to figure out if it is a list or not. I don't think there is a magic solution. It isn't even right to assume that a single key query should return all matches, because that destroys the order that you put them in. Ns_set preserves the order, which could be important.

In reverse:

  1. There is no reason a ns_set get_all should destroy the order of the subset.
  2. You don't need to test for list existence if you are writing in a functional iterator style. Take something simple, like pulling multiple form args into a SQL query to be executed:
    url_query = conn.query
    url_query.get_all('orderby').each { |value|  append sql_query ",$value" }
    
  3. I'm a big fan of data modeling at all levels of the application. If you have to wonder if the result is a list, as opposed to 'the form vars can have 0 to N values', then the data is not specified enough.

David, thanks for the suggestion. Maybe that is sufficient to make me shut up. :)