NeoCSV nil-Handling

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

NeoCSV nil-Handling

Sean P. DeNigris
Administrator
I'd like a hook to specify default values more dynamically. The use case is
that I created a glue layer between Magritte and NeoCSV so one can
meta-describe how to extract CSV fields into objects.

For example:
```
descriptionDate
        <magritteDescription>
       
        ^ MADateDescription new
                        accessor: #date;
                        priority: 400;
                        propertyAt: #csvFieldName put: 'Date';
                        propertyAt: #csvReader put: [ :s | (s, '/2017') asDate ];
                        default: Date today;
                        yourself
```

The problem is that there doesn't seem to be a way to plug #default: above
into NeoCSV because other hooks like #addField:converter: seem to be skipped
for nil values, shortcutting to a statically described per-csv-file
emptyFieldValue.



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: NeoCSV nil-Handling

Sven Van Caekenberghe-2
Sean,

> On 13 Feb 2018, at 14:39, Sean P. DeNigris <[hidden email]> wrote:
>
> I'd like a hook to specify default values more dynamically. The use case is
> that I created a glue layer between Magritte and NeoCSV so one can
> meta-describe how to extract CSV fields into objects.
>
> For example:
> ```
> descriptionDate
> <magritteDescription>
>
> ^ MADateDescription new
> accessor: #date;
> priority: 400;
> propertyAt: #csvFieldName put: 'Date';
> propertyAt: #csvReader put: [ :s | (s, '/2017') asDate ];
> default: Date today;
> yourself
> ```
>
> The problem is that there doesn't seem to be a way to plug #default: above
> into NeoCSV because other hooks like #addField:converter: seem to be skipped
> for nil values, shortcutting to a statically described per-csv-file
> emptyFieldValue.

The initial idea of the empty value (defaulting to nil) and the short circuiting of further conversion, is precisely to help in the writing of the converter blocks, so that

 [ :s | s asDate ]

will never receive nil or an empty string and consequently does not have to test on it.

I suppose I could imagine an option like #passEmptyFieldsToConverters, which would allow (and force you) to write converter blocks like

 [ :s | s isEmptyOrNil ifTrue: [ Date doomsDay ] ifFalse: [ s asDate ] ]

so that you can specify your own custom empty value per field.
What do you think ?

Sven
 
Reply | Threaded
Open this post in threaded view
|

Re: NeoCSV nil-Handling

Sean P. DeNigris
Administrator
Sven Van Caekenberghe-2 wrote
> What do you think ?

Could #emptyFieldValue: accept a block instead of the actual value? Or be
per-field? Or both? Then the default could still be set via the current
mechanism, keeping the usual API simple, but the user would have a bit more
control.



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: NeoCSV nil-Handling

Sven Van Caekenberghe-2
Sean,

> On 19 Feb 2018, at 02:33, Sean P. DeNigris <[hidden email]> wrote:
>
> Sven Van Caekenberghe-2 wrote
>> What do you think ?
>
> Could #emptyFieldValue: accept a block instead of the actual value? Or be
> per-field? Or both? Then the default could still be set via the current
> mechanism, keeping the usual API simple, but the user would have a bit more
> control.

Have a look at the following:

===
Name: Neo-CSV-Core-SvenVanCaekenberghe.27
Author: SvenVanCaekenberghe
Time: 19 February 2018, 10:28:24.688684 pm
UUID: a08d6c1c-f921-0d00-aaa4-29b9044088b7
Ancestors: Neo-CSV-Core-SvenVanCaekenberghe.26

Add special option #passNil for NeoCSVReader>>#emptyFieldValue: so that converter blocks do get nil passed in for empty/missing fields and can act accordingly

Add NeoCSVReaderTests>>#testEmptyFieldValuePassNil
===
Name: Neo-CSV-Tests-SvenVanCaekenberghe.24
Author: SvenVanCaekenberghe
Time: 19 February 2018, 10:28:03.52381 pm
UUID: 1598291b-f921-0d00-aaa3-c7c0044088b7
Ancestors: Neo-CSV-Tests-SvenVanCaekenberghe.23

Add special option #passNil for NeoCSVReader>>#emptyFieldValue: so that converter blocks do get nil passed in for empty/missing fields and can act accordingly

Add NeoCSVReaderTests>>#testEmptyFieldValuePassNil
===

Now you can do as follows:

| date1 date2 |
date1 := '1900-01-01' asDate.
date2 := '2000-12-31' asDate.
self
  assert: ((NeoCSVReader on: 'date1,date2\2018-01-01,2018-02-01\2018-01-01,\,2018-02-01\\' withCRs readStream)
    emptyFieldValue: #passNil;
    addFieldConverter: [ :input | input ifNil: [ date1 ] ifNotNil: [ input asDate ] ];
    addFieldConverter: [ :input | input ifNil: [ date2 ] ifNotNil: [ input asDate ] ];
    skipHeader;
    upToEnd)
equals: (Array
    with: (Array with: '2018-01-01' asDate with: '2018-02-01' asDate)
    with: (Array with: '2018-01-01' asDate with: date2)
    with: (Array with: date1 with: '2018-02-01' asDate)
    with: (Array with: date1 with: date2)).

Note how the first field's default empty value is now date1 and second field's is date2.

Sven