print "Hello", so no simpler could it be. But if it can be corrected, please tell me, is https://github.com/red/red/issues the place to raise the issue? Or some other specific place?
>> try [date? a: 29-02-2019] *** Script Error: cannot MAKE/TO date! from: [day month year] *** Where: do *** Stack: load >> attempt [date? a: 29-02-2019] *** Script Error: cannot MAKE/TO date! from: [day month year] *** Where: do *** Stack: load
@lpvm you can see that the error comes in
loading the value, which is separate from evaluation (that
attempt will catch).
attempt/safer also doesn't catch it. A couple alternatives:
>> attempt [make date! [2019 02 29]] == none
>> load/trap "date? a: 29-02-2019" == [[date? a:] "29-02-2019" make error! [ code: 349 type: 'script id: 'bad-to-arg arg1: date! arg2: [d...
There can be a bigger discussion on loadability and literal values, if needed.
Load is a safe operation, even on untrusted data, though we should always test and ensure that. All it should do is transcode a string of data (text or binary) into Red values. Anytime you get user input (including from other devs in extensible systems), it's going to be in one of those forms. That makes
load your first friend in dialect processing, because then you can
parse at the block level.
With Red, there is almost never a single way to do things, as with some other langs.
load/trap is really powerful, in that you can tell whether an error occurred at all, and point people to the problem. Much easier than trying to do all the parsing on the string yourself.
@lpvm When you
load a string you will have a block of values, those values are words (like
tuple!) and literals (like
firstname.lastname@example.org etc.), and the words in your loaded block can either have values as well, for example
tuple! is a word that has a value of a
So you can execute (evaluate) your loaded block (if you trust it), or parse it, or use that block to create values in your script (like a configuration file etc.)
>> load "print [3 * 5 email@example.com]" == [print [3 * 5 firstname.lastname@example.org]] ; here we have a block with words & values only, two words print and *, two literals 3 and 5, and one another literal which is an email >> do load "print [3 * 5 email@example.com]" >> do "print [3 * 5 firstname.lastname@example.org]" 15 email@example.com ; do without load also loads the string (or file) before evaluating >> load "a: 1 b: 2" == [a: 1 b: 2] ;just two words a: & b:, and two literals 1 & 2, doesn't mean anything without a further process like parsing or evaluating >> construct load "a: 1 b: 2" == make object! [ a: 1 b: 2 ] ; now we have something more useful
So loadable strings are more valuable then ordinary strings :)
to-date1: func [value][ to-date switch type?/word :value [ string! [if find value dot [replace/all value dot space] load value] block! [value] object! map! [reduce [value/year value/month value/day]] ]] to-date1 "2-12-2000" ;== 2-Dec-2000 to-date1 "2000/12/2" ;== 2-Dec-2000 to-date1 "2.12.2000" ;== 2-Dec-2000 to-date1 #(year: 2000 month: 12 day: 31) ;== 31-Dec-2000 to-date1 [2 12 2000] ;== 2-Dec-2000
do %values.redand then
:lscript.red, check its structure with
vs, take a look at some function with eg.