eZ Community » Forums » eZ Publish 5 Platform » Semantics vs. pragmatism in action:...
expandshrink

Semantics vs. pragmatism in action: to cast or not to cast

Semantics vs. pragmatism in action: to cast or not to cast

Friday 08 March 2013 11:25:32 am - 9 replies

As a follow up to Eirik's insightful post about Semantics vs. pragmatism, I have an actual very specific question for you developers.

When creating FieldType Value objects, you can feed the constructor with several primitive types. For instance, Keyword\Value() accepts an array of keywords, or a comma separated list of keywords. The constructor will take care of the transformation process.

Now we are wondering about something quite general here: how much laxism do you think we should allow ? Allowing laxism is also encouraging it. We all know how projects go.

Here is an example. How would you like the constructor to react in this example:

 new Integer\Value( "42" );

Should it cast "42" to an integer, or throw an InvalidArgumentException ?

If we want to encourage best practices, and keep the API strict, it would be the exception. It would avoid errors when assigning values, and would probably help developers figure out those mistakes earlier. On the other hand, PHP isn't a strict language. Do we want to force it to be one ?

There is a border case that is also interesting. What do you think these should do ?

 new Integer\Value( "NaN" );
 new Integer\Value( "9.1" );

I would say that in the first case, I would expect an exception to be thrown. This is clearly a mistake. The second one ? Not entirely sure...  maybe I'm just expecting the type to store a rounded value. It's not very, very clean, but...

Modified on Friday 08 March 2013 11:36:33 am by Bertrand Dunogier

Friday 08 March 2013 12:03:32 pm

I would prefer the exception personally as it would mean discovering problems earlier and fixing them earlier.

As for the other two cases I would expect an exception for the first one. For the second if the solution is casting it to an integer, then obviously the rules of casting would apply and round it down to 9.

Cheers,

Peter

Friday 08 March 2013 12:07:47 pm

This is an interesting question. From an engineering perspective, I think the most appropriate approach would be to require strict adherence to the expected inputs. But this is indeed very uncommon for PHP, and I think we have to take human factors into consideration. 

Developer adoption of the framework will depend in part on how easy it is to use. Developers are already going to generate enough errors when working with the API as it is, that I don't see the need to get in their way when we can determine the intent without much extra effort. 

My thought would be to have Integer\Value in this example do an internal is_numeric check and throw an exception of it fails. Perhaps additionally run is_integer and log a warning (but don't throw an exception). Meticulous developers will go find what's causing those and clean them up.

Philosophically, do we value correctness more, or ease of use? It's a tough question, but I want to see eZ used as much as possible, so I'd go with ease of use.

Friday 08 March 2013 12:16:33 pm

+1. I would prefer the exception for first case. as i would prefer it we went like

<span style="font-size: 1.1em;">new Integer\Value( true );</span>

Further more, we are told to do strict comparasions too, that's it "===" instead of "==". so i would go for the exception

i admit last case can have other point of view, but maybe i would go for the exception or maybe for the warning.

but well, what about if a constructor expects an object and you don't pass an object there? Would you expect that function to "cast it to object"? maybe i'm too brute here, but at the end my point is that if you don't cast in some cases, maybe you shouldn't do in others... 

 

 

Modified on Friday 08 March 2013 12:26:15 pm by Carlos Revillo

Friday 08 March 2013 2:48:56 pm

Well, thing is Carlos that the constructor of Value is pretty much the only one with logic (except for fromHash in the Type class). If you want some flexibility at all, that's where it must be.

On the other hand, a transparent cast may seem like laxism, but PHP isn't famous for its strong typing... you can easily work out with integers stored in strings and still get your results.

I'd say that in that case, we could allow integers, and string containing only integers, e.g. "1" is valid, "1.1 or "hello" get an exception (or a warning, it may be nicer, but we're not down there yet).

Friday 08 March 2013 3:08:02 pm

Quote from Joe Kepley :

My thought would be to have Integer\Value in this example do an internal is_numeric check and throw an exception if it fails. Perhaps additionally run is_integer and log a warning (but don't throw an exception). Meticulous developers will go find what's causing those and clean them up.

Just be aware that Public API is strict, it cares first and foremost about data consistency, we did a clear choice to make it strict when we started making it as we saw the error only model of 4.x as a weakness.

So unless we re-define that Public API should do silent casts for you with data loss, it should only take values considered as int (string or native integer).
More flexibility with warnings / errors should be done at a higher level, in case of user input: forms validation

Open question is how to make sure that you can also use this less strict layer in data imports and other sources where want eZ Publish to fix the data for us but keep a log of errors / warnings.

Modified on Friday 08 March 2013 3:09:02 pm by André R

Friday 08 March 2013 5:11:31 pm

André, good point about strict typing at low levels. I guess it makes sense to put the type sanitizing at the "edges" of the architecture. 

As to how to relax this for data imports, I'm guessing there will need to be some wrappers available. eZ/DrunkAndHappyAPIBundle?

Saturday 09 March 2013 12:35:23 am

DrunkenDataImport happy.gif Emoticon

Sunday 10 March 2013 12:07:09 pm

Actually, I care less about whether the cast is done or not, as much as I care that the process is clearly documented: which fieldType methods are called when? Who takes care of validation? How can validation be bypassed? Is there standard format for serialization, and if so, what is it?

For ezp4, this was never the case, for many historical reasons mostly. A short list of bad smells:

- main datatype validation routines are tied to http requests (lack of vision: CMS is not only used via its main GUI)

- many fromstring() calls have been coded so that they will not reset an exiting non-null value to a null value (lack of vision: coder only thought about data creation and not data update)

- fromstring() usage of commas, dashes and whatnot for lists and nested data is very inconsistent

- when trying to update datatypes which contain relations, and an id is passed in to a non-existing related content, what does happen? Is there some automatic-fix strategy available to make import of not-so-consistent-data doable at all?

- etc...

(Sorry if this was offtopic wrt. the original question; just a small rant due to having worked too much with old API happy.gif Emoticon The fact that this question is asked in the 1st place, and that work is already ongoing to document the new API, at https://jira.ez.no/browse/EZP-20473, makes me think that we are on a much better track for the future!)

Modified on Monday 11 March 2013 10:26:01 am by Gaetano Giunta

Monday 11 March 2013 10:45:09 am

Thanks for quoting https://jira.ez.no/browse/EZP-20473, Gaetano !

This issue is actually quite a large one, and affects all developers. It aims at writing a good reference for our FieldTypes: what data you feed them with, what you are given back by them, validation, etc.

It explains how this must be done (what parts of the code must be inspected, and so on), and should actually help you understand the Public API behind field types.

Do not hesitate to comment on it and add your feedback. Remember that you can also watch issues, and vote for them. It may encourage Ricardo blunk.gif Emoticon

expandshrink

You must be logged in to post messages in this topic!

36 542 Users on board!

Forums menu

Proudly Developed with from