From: Jakub Narebski <jnareb@gmail.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCHv2 2/8] gitweb: Option for filling only specified info in fill_project_list_info
Date: Wed, 22 Feb 2012 23:05:12 +0100 [thread overview]
Message-ID: <201202222305.14387.jnareb@gmail.com> (raw)
In-Reply-To: <7vfwe6ng8u.fsf@alter.siamese.dyndns.org>
On Mon, 20 Feb 2012, Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
>
> > Introduce project_info_needs_filling($pr, $key[, \%fill_only]), which
>
> That's "project_info_needs_filling($pr, @key[, \%fill_only])", isn't it?
Yes it is. I'm sorry, I have missed that this needs fixing from the
first version of patch series. Since then I have noticed that in few
cases we fill two fields at once, so we have to ask about two fields
at once as well.
> > +# entry for given @keys needs filling if at least one of interesting keys
> > +# in list is not present in %$project_info; key is interesting if $fill_only
> > +# is not passed, or is empty (all keys are interesting in both of those cases),
> > +# or if key is in $fill_only hash
> > +#
> > +# USAGE:
> > +# * project_info_needs_filling($project_info, 'key', ...)
> > +# * project_info_needs_filling($project_info, 'key', ..., \%fill_only)
> > +# where %fill_only = map { $_ => 1 } @fill_only;
>
> The reason this spells bad to me is that it gives the readers (and anybody
> who may want to touch gitweb code) that the caller has _two_ ways to say
> the same thing.
>
> If a caller is interested in finding out $key in $project_info, it can
> either (1) pass $key as one of the earlier parameters to the function and
> not pass any \%fill_only, or (2) pass $key and pass \%fill_only but after
> making sure \%fill_only also has $key defined.
>
> And if the caller passes \%fill_only, it has to remember that it needs to
> add $key to it; otherwise the earlier request "I want $key" is ignored by
> the function.
Yes, you are right. All of this is caused by fill_project_list_info()
trying to do *two* things, instead of doing one thing and doing it well,
as is Unix philosophy. It tried to check both that key is needed and
that key is wanted.
> Why is it a good thing to have such a convoluted API?
Thanks for a sanity check.
> Is it that "fill_project_list_info" is called by multiple callers, and
> they do not necessarily need to see all the fields that can be filled by
> the function (namely, age, age_string, descr, descr_long, owner, ctags and
> category)? If that is the case, I must say that the approach to put the
> set filtering logic inside project_info_needs_filling function smells like
> a bad API design.
You are right.
> In other words, wouldn't a callchain that uses a more natural set of API
> functions be like this?
>
> # the top-level caller that is interested only in these two fields
> fill_project_list_info($projlist, 'age', 'owner');
>
> # in fill_project_list_info()
> my $projlist = shift;
> my %wanted = map { $_ => 1 } @_;
>
> foreach my $pr (@$projlist) {
> if (project_info_needs_filling($pr,
> filter_set(\%wanted, 'age', 'age_string'))) {
That or
if (project_info_needs_filling($pr, 'age', 'age_string') &&
project_info_is_wanted(\%wanted, 'age', 'age_string')) {
and in your case there is no duplication of field names.
filter_set() is simply intersection of two sets, but it treats empty
%wanted as a full set.
> ... get @activity ...
> ($pr->{'age'}, $pr->{'age_string'}) = @activity;
> }
> ...
> }
>
> That way, "needs_filling" has to do one and only one thing well: it checks
> if any of the fields it was asked is missing and answers. And a generic
> set filtering helper that takes a filtering hashref and an array can be
> used later outside of the "needs_filling" function.
Right.
> > sub project_info_needs_filling {
> > + my $fill_only = ref($_[-1]) ? pop : undef;
> > my ($project_info, @keys) = @_;
> >
> > # return List::MoreUtils::any { !exists $project_info->{$_} } @keys;
> > foreach my $key (@keys) {
> > - if (!exists $project_info->{$key}) {
> > + if ((!$fill_only || !%$fill_only || $fill_only->{$key}) &&
> > + !exists $project_info->{$key}) {
> > return 1;
> > }
> > }
> > return;
> > }
> >
> > -
>
> Shouldn't the previous patch updated not to add this blank line in the
> first place?
O.K.
> > # fills project list info (age, description, owner, category, forks)
>
> Is this enumeration up-to-date? If we cannot keep it up-to-date, it may
> make sense to show only a few as examples and add ellipses.
O.K.
> > # for each project in the list, removing invalid projects from
> > -# returned list
> > +# returned list, or fill only specified info (removing invalid projects
> > +# only when filling 'age').
>
> It is unclear what the added clause wants to say; especially, the link
> between the mention of 'age' and 'only when' is unclear. Is asking of
> 'age' what makes a request a notable exception to remove invalid projects?
> Or is asking to partially fill fields what triggers the removal of invalid
> projects, and you mentioned 'age' as an example?
>
> If it is the former (I am guessing it is), it would be much clearer to
> say:
>
> Invalid projects are removed from the returned list if and only if you
> ask 'age' to be filled, because of such and such reasons.
O.K.
Sidenote: the reason is that to check that project is valid you really
have to run git command that requires repository in it[1]. Only when
filling 'age' and 'age_string' using git_get_last_activity() we always
run git command.
[1] Gitweb actually uses --git-dir=<PATH> parameter to git wrapper.
--
Jakub Narebski
Poland
next prev parent reply other threads:[~2012-02-22 22:05 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-15 20:38 [PATCHv2 0/8] gitweb: Faster and improved project search Jakub Narebski
2012-02-15 20:38 ` [PATCHv2 1/8] gitweb: Refactor checking if part of project info need filling Jakub Narebski
2012-02-15 20:38 ` [PATCHv2 2/8] gitweb: Option for filling only specified info in fill_project_list_info Jakub Narebski
2012-02-20 6:58 ` Junio C Hamano
2012-02-22 22:05 ` Jakub Narebski [this message]
2012-02-15 20:38 ` [PATCHv2 3/8] gitweb: Faster project search Jakub Narebski
2012-02-20 8:33 ` Junio C Hamano
2012-02-15 20:38 ` [PATCHv2 4/8] gitweb: Introduce esc_html_hl_regions Jakub Narebski
2012-02-15 20:38 ` [PATCHv2 5/8] gitweb: Highlight matched part of project name when searching projects Jakub Narebski
2012-02-15 20:38 ` [PATCHv2 6/8] gitweb: Highlight matched part of project description " Jakub Narebski
2012-02-15 20:38 ` [PATCHv3/RFC 7/8] gitweb: Highlight matched part of shortened project description Jakub Narebski
2012-02-15 20:38 ` [PATCHv2 8/8] gitweb: Use esc_html_match_hl() in 'grep' search Jakub Narebski
2012-02-16 20:40 ` [PATCHv2 0/8] gitweb: Faster and improved project search Junio C Hamano
2012-02-16 21:53 ` Jakub Narebski
2012-02-20 7:09 ` Junio C Hamano
2012-02-22 22:09 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201202222305.14387.jnareb@gmail.com \
--to=jnareb@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).