On Sun, Mar 30, 2008 at 05:51:24AM -0400, rgheck wrote:
>
> So, to get everyone up to speed, Bo and I disagree about a question 
> concerning the design of InsetBibtex and, in particular, about how the 
> parameters of the inset should be handled. The original code, written (I 
> believe) by Georg back when the new InsetCommandParams structure was 
> conceived, handles the parameters via the InsetCommandParams structure. The 
> existing code, which Bo introduced a while back in connection with the 
> embedding feature, changes this. Where the old code would have used 
> InsetCommandParams, Bo uses an EmbeddedFileList, which is in the inset for 
> other reasons and which becomes the primary representation of the 
> parameters---primary in the sense that it's what gets used when the 
> parameters need to be known. The InsetCommandParams are reconstructed from 
> the EmbeddedFileList for use by e.g. the write() routine.
>
> This has led to problems, because *.bib files aren't to be associated with 
> locations in the filesystem, and EmbeddedFile subclasses FileName and so 
> represents them exactly that way. (As JMarc has pointed out, there are 
> likely similar problems elsewhere. This will affect any case where the 
> file's actual location might be indifferent to TeX.) In short, the problem 
> is that, in the code, the "bibfiles" parameter might have looked like this:
>    biblio,chomsky
> whereas in the new code it looks like this:
>    /path/to/lyx/file/biblio.bib,/path/to/lyx/file/chomsky.bib
> The question is how to solve this problem.

So far it looks like we'd need a class 'EmbeddedObject', that's not
derived from FileName, but, possibibly, has a 'fileName()' method to
get a 'real' FileName if that is needed.

> Bo has a patch that adds "metadata" to the EmbeddedFile object and then 
> uses this metadata to reconstruct the parameters. The patch could be made 
> to work, but I feel quite strongly that this is wrong. I would prefer to go 
> back more to the older representation, using InsetCommandParams as the 
> primary representation---in the sense that it's what you consult when you 
> want to know about the parameters---and then constructing the 
> EmbeddedFileList from it when and as necessary.
>
> Note that, either way, we have to go back and forth between these 
> somewhere. This is unfortunate, but it seems built into the way embedding 
> works right now. (I've got other questions about whether it should work 
> that way, but that's a separate issue.)
>
> It's seems pretty clear at this point that Bo and I don't agree, so the 
> advice of others would be welcome.
>
> My reason to prefer my solution is simple. About a year ago, I tried to 
> solve some crashes related to InsetCommandParams. I posted a patch, which 
> got me a long and informative lecture from Georg and Abdel about why 
> InsetCommandParams and InsetCommand need to be kept separate. The thread 
> begins here:
>    http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg114235.html
> and Georg's sternest lecture is here:
>    http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg114325.html
> After studying the code, I came to agree with Georg, and after 1.5 came 
> out, I re-worked InsetCommandParams to fix the crashes in question and, as 
> a result, came even more to understand why the InsetCommand stuff is 
> organized the way it is. So I think I have some understanding of this part 
> of the code.
>
> The issue is not how the parameters are represented. The issue is *how an 
> InsetCommand interacts with its parameters*. The design is that the 
> parameters are stored in InsetCommandParams, and the inset interacts with 
> them via the methods of InsetCommandParams. Whether there are good reasons 
> for this---even though there are---is almost irrelevant, because that is 
> how the code is organized. One could do something like this:
>    InsetCommand * inset = getCommandInset(); // could be anything
>    InsetCommandParams icp;
>    InsetCommand::string2params(insetName(inset.lyxCode(), paramStr, icp);
>    inset.setParams(icp);
> (You could re-organize part of the inset factory this way if you wanted 
> to.) If one did that sort of thing now, it could lead to a crash, because 
> the EmbeddedFileList would be out of sync with the parameters.

And right now I start to get the impression that we a close to one of
our good old attempts to abstract where abstraction isn't called for.

To play the devil's advocate: What would be wrong with 

   virtual string InsetCommand::parametersToString() const;

and

   virtual void InsetCommand::parametersFromString(string const &);

with suitable implementations in all derived classes? Common code
could be put as helper method into InsetCommand.

What exactly is InsetCommandParameter used for?

Inset construction from a string?
-> We can construct an 'empty' isnet and call parametersFromString() on it.

Storing temporary copies in the dialogs?
-> Store a stringified version there. We convert it to a string anyway
when dispatching.

> Now there are ways around this sort of thing, to be sure. But my point
> is that, however we approach this, we should use the existing
> interface.

We can change interfaces, we can keep them. That's no strong argument.

> The parameters should be the parameters, and the code
> should interact with them in the way it would if there were no
> EmbeddedFileList in InsetBibtex.  That's my main point, so let me say
> it again: The parameters should be the parameters, and the code should
> interact with them in the way it would if there were no
> EmbeddedFileList in InsetBibtex. For one thing, maybe at some point
> there is no longer an EmbeddedFileList there, because the
> implementation of the embedding feature changes again; we should limit
> the re-writing required in that case and make sure that changes to
> that code don't affect this code. But even if it doesn't ever change,
> it just doesn't seem sensible to me that the introduction of this
> feature should have required such wholesale changes to the way
> InsetBibtex works that, having spent as much time with it as I
> have---I also reworked the way BibTeX data is represented---it took me
> several hours to figure it out again and even more to figure out why
> kpsewhich support was broken. A newcomer to the code who had figured
> out how most InsetCommand derivatives work would be lost here.
>
> Even if we do things my way, we still have to keep the
> EmbeddedFileList sync'd with the parameters, but the conversion should
> be automatic and encapsulated it in overridden methods, e.g.: void
> setParams(InsetCommandParams const & icp) {
> InsetCommand::setParams(icp); updateEmbeddedFiles(); // this could
> modify the params if embedding fails } We'll have to handle other
> methods, too, and that will take work and mean more code. But the
> issue isn't LOC but maintainability, and a lot of the required code
> has to do with the facts (a) that ICP stores and reports all
> parameters as strings, whereas our parameters represent lists, and (b)
> that we have two lists, bibfiles and embed, that we need to iterate
> over together. It's kind of messy. (The really dramatic way to do this
> would be to subclass InsetCommandParams, but I don't think we need to
> go that far.)

Typically maintainability increases as LOC decrease. There are
exceptions, of course...

> Well, that's my case. Bo, you want to state yours?

;-)

No matter what he says I wonder whether the dispute is on the right
level. I question I see is whether InsetCommandParams is the right thing
to use (a) in this case, and (b) in general.

Note that it original structure was just a convenient way to pass two or
three data items typically associated with a simple LaTeX commands
around. Nowadays it looks like a ton of bureaucracy sparking three-week
discussions...

Andre'

Reply via email to