-
Notifications
You must be signed in to change notification settings - Fork 669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First pass at defining some common collection interfaces #7941
Conversation
* | ||
* @return Collection | ||
*/ | ||
public function filter(callable $filter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was this moved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alphabetizing
@mrclay I know this is kind of a big one, but I'd appreciate your input. |
Could you squash the commits? Would make it easier to read. |
It would be helpful to have some idea of where you can imagine all of these being used. Do we pull in the whole thing regardless? I'd lean towards implementations deciding how to handle duplicate insertions. I have cases where that makes sense and where it doesn't. Generics... I think we get most of the win via static analysis, so I'm not all that into runtime checks. I feel like sorting and filtering is often so custom (and operations are so frequently dependent on the underlying data storage API) that putting it in the main interfaces seem limiting. E.g. ElggList is going to be a link table. Would sorting it create a new list ID and a copy of all the elements? I can't imagine we'd want that. |
@juho-jaakkola -- you can just look at the Files Changed tab? |
@mrclay sorting an entity list does not mutate the list or create a new DB entry, it is just a virtual view over it. exactly analagous to using ORDER BY in SQL. The default order of lists would be specified by their items' position property in the DB. |
@mrclay Another option is to define alternative methods that are guaranteed not to throw when they fail to perform their intended operation (e.g. "offer" which returns false instead of "add" which throws). I feel this bloats the API, though, so I'm not super keen on it. |
Brain dump: would also like a WritableRepository interface that extends Sequence. This would be one of the ultimate practical uses for the genetic collections APIs. If we can model our data storage as a collection, it will become trivial to write tests for it or swap out back ends.
T may need to extend a RepositoryEntry interface that implements a getId method... Otherwise there is no way to get the ids of new items... |
@mrclay to answer your question about what these would be used for, the high level thought is just "any time you would return an array, return a collection instead". But just to be clear, some concrete examples:
function addTranslation($country_code, $language_array) {
if (!isset($this->CONFIG->translations)) {
$this->CONFIG->translations = array();
}
$country_code = strtolower($country_code);
$country_code = trim($country_code);
if (is_array($language_array) && sizeof($language_array) > 0 && $country_code != "") {
if (!isset($this->CONFIG->translations[$country_code])) {
$this->CONFIG->translations[$country_code] = $language_array;
} else {
$this->CONFIG->translations[$country_code] = $language_array + $this->CONFIG->translations[$country_code];
}
return true;
}
return false;
} With a standard collections API and some trivial implementations, this code could almost be simplified to: addTranslation($country_code, Map $language_array) {
$this->translations->get($country_code)->addAll($language_array);
} |
Latest idea: what if I just put all this stuff in its own repo? I can see these being very useful outside of Elgg, and having them in a separate repo makes that much easier... Then we can just include them in |
Is it worth looking into the other popular collections repos? https://packagist.org/search/?q=colle |
Great point. I actually did look around a bit already. It would be good to
Happy to use any of these as an implementation detail, but I really feel Happy to put my research into a spreadsheet or something, just to be On Tue Feb 24 2015 at 1:07:33 PM Steve Clay notifications@github.com
|
I also looked at https://github.com/IcecaveStudios/collections and they At the end of the day I think what I want is total control over the So I take back the idea of putting these in a separate repo. I don't want On Tue Feb 24 2015 at 2:53:06 PM Evan Winslow evan@elgg.org wrote:
|
Agreed. |
One obvious use-case for Map in case I haven't yet mentioned it is i18n stuff. Basically this is a Map of locales to message bundles, where message bundles are maps of strings to Messages. Messages can be formatted with arguments to produce fully localized strings. |
Added a spreadsheet which is the start of further research into the existing collection interfaces that are out there |
Comparison of collection libraries/interfaces
https://docs.google.com/a/elgg.org/spreadsheets/d/1a7krO6pIQPm52Y8tKYr8JOPvOrrTlohty59W7MRz6Fk/edit#gid=0
Believe it or not, I've tried to keep this down to the minimum number of interfaces I think we'd need if we migrated all our array-based interfaces to be collections-based. Because of my philosophy of "promise the least API surface possible", we have lots of fine-grained interfaces which allow us to do just that, which makes this feel a more complicated than just using arrays, but the possibilities for performance and developer appeal are fantastic, I think, compared to arrays.
I find this significantly cleaner that the current approach:
TODOs:
Queue
inherit fromSequence
. This requires implementors to provide all the iteration helpers (filter/map/etc.), which we don't necessarily want to do (e.g. seeElgg\Queue\DatabaseQueue
, which does not need all those things to do its job).For discussion:
Collection
instead of justSequence
?Sequence
andCollection
interfaces, which feels wrong.Set
that already contains it?Map
accessors be?Sequence
accessors be?