I am writing some Velocity Script as part of a Marketo email template that requires that I check if an boolean attribute on a lead is set or not.
When I attempt to display something associated with a lead in my system I can do something like;
{{lead.myName}}
This also works for fields that have spaces in them;
{{lead.my name}}
When it comes to using that field for #setting or #ifing something then it doesn't work as well.
#if($lead.my name) throws an error saying that an unexpected space has been found.
I have tried variants like #if(${lead.my name}) to no avail.
Any help / pointers would be massively helpful.
Actual use case
In my example the field I need to access is called lead.Subscribed to Innovation (L) 1, I don't think the brackets will cause a problem, certainly any error messages have been space related.
According to User Guide variables cannot have spaces
A VTL Identifier must start with an alphabetic character (a .. z or A .. Z). The rest of the characters are limited to the following types of characters:
alphabetic (a .. z, A .. Z)
numeric (0 .. 9)
hyphen ("-")
underscore ("_")
even with the curly brackets :
this is valid:
#set( ${myemail} = "email#email.com" )
while trhis is invalid:
#set( ${my email} = "email#email.com" )
My best guess will be to change the source system to comply with the velocity naming convention.
Related
I'm indexing documents which contain normal text, programming code and other non-linguistic fragments. For reasons which aren't particularly relevant I am trying to tokenise the content into lowercased strings of normal language, and single character symbols.
Thus the input
a few words. Cost*count
should generate the tokens
[a] [few] [words] [.] [cost] [*] [count]
Thus far thus extremely straightforward. But I want to handle "compound" words too, because the content can include words like order_date and object-oriented and class.method as well.
I'm following the principle that any of [-], [_] and [.] should be treated as a compound word conjunction rather than a symbol IF they are between two word characters, and should be treated as a separate symbol character if they are adjacent to a space, another symbol character, or the beginning or end of a string. I can handle all of this with a PatternTokenizer, like so:
public static final String tokenRgx = "(([A-Za-z0-9]+[-_.])*[A-Za-z0-9]+)|[^A-Za-z0-9\\s]{1}";
protected TokenStreamComponents createComponents(String fieldName) {
PatternTokenizer src = new PatternTokenizer(Pattern.compile(tokenRgx), 0);
TokenStream result = new LowerCaseFilter(src);
return new TokenStreamComponents(src, result);
}
This successfully distinguishes between full stops at the end of sentences and full stops in compounds, between hyphens introducing negative numbers and hyphenated words, etc. So in the above analyzer, the input:
a few words. class.simple_method_name. dd-mm-yyyy.
produces the tokens
[a] [few] [words] [.] [class.simple_method_name] [.] [dd-mm-yyyy] [.]
We're almost there, but not quite. Finally I want to split the compound terms into their parts RETAINING the trailing hyphen/underscore/stop character in each part. So I think I need to introduce another filter step to my analyzer so that the final set of tokens I end up with is this:
[a] [few] [words] [.] [class.] [simple_] [method_] [name] [.] [dd-] [mm-] [yyyy] [.]
And this is the piece that I am having trouble with. I presume that some kind of PatternCaptureGroupTokenFilter is required here but I haven't been able to find the right set of expressions to get the exact tokens I want emerging from the analyzer.
I know it must be possible, but I seem to have walked into a regular expression wall that blocks me. I need a flash of insight or a hint, if anyone can offer me one.
Thanks,
T
Edit:
Thanks to #rici for pointing me towards the solution
The string which works (including support for decimal numbers) is:
String tokenRegex = "-?[0-9]+\\.[0-9]+|[A-Za-z0-9]+([-_.](?=[A-Za-z0-9]))?|[^A-Za-z0-9\\s]";
Seems to me like it would be easier to do the whole thing in one scan, using a regex like:
[A-Za-z0-9]+([-_.](?=[A-Za-z0-9]))?|[^A-Za-z0-9\\s]
That uses a zero-width forward assertion in order to only add [-._] to the preceding word if it is immediately followed by a letter or digit. (Because (?=…) is an assertion, it doesn't include the following character in the match.)
To my mind, that won't correctly handle decimal numbers; -3.14159 will be three tokens rather than a single number token. But it depends on your precise needs.
I'm working with an API that returns an array of objects. I can get all the keys, but two of those have numbers as keys, and I cannot get it. Give me an error.
I really dont know why I can not get it those keys.
Is there something different due to are numbers?
BTW Im using axios.
If you're using dot notation, you should change to bracket notation to access properties start by a number.
The code below uses dot notation, it throws an error
const test = {"1h" : "test value"};
console.log(test.1h); // error
Why :
In the object.property syntax, the property must be a valid JavaScript
identifier.
An identifier is a sequence of characters in the code that identifies a variable, function, or property.
In JavaScript, identifiers are case-sensitive and can contain Unicode letters, $, _, and digits (0-9), but may not start with a digit.
The code below uses bracket notation, works fine
const test = {"1h" : "test value"};
console.log(test["1h"]); // works
Why :
In the object[property_name] syntax, the property_name is just a
string or Symbol. So, it can be any string, including '1foo', '!bar!',
or even ' ' (a space).
Check out the document here
Why velocity gives the following output for the string
VelocityContext vc = new VelocityContext();
vc.put("foo", "bar");
String inString = "THis is ${{foo}} and this is ${foo}.Hello and ${foo}-Hello";
StringWriter sw = new StringWriter();
ve.evaluate(vc, sw, "Tag", inString);
Output:
THis is ${{} and this is bar.Hello and bar-Hello
I was expecting it would either print ${{foo}} or {bar}, why ${{}? Would double curly act as escape character?
I'm using this under strict reference mode set as true. And I neither see an exception nor I see it print it as is and that's what is confusing me.
Well, you made me look into the code and I'm not sure if I understood it correctly. The problem seems to be that in ${...}, the xxx is treated as an ASTReference, which then gets tokenized differently than a standalone string "{bar}". Specifically, it get tokenized into 3 tokens {, bar and }. Then the engine tries to find the so-called root of the reference (in ${x}, the root is x), does not recognize the pattern and goes into a fallback reference type RUNT, which says that the first token, i.e. "{" matters. This way "{bar}" becomes "{".
In other words, the expression ${{bar}} does not make sense and Velocity fails to throw an error here. In other nonsensical combinations like ${[bar]} it actually throws an error.
Velocity Variables or VTL Identifier
Must start with an alphabetic character (a .. z or A .. Z). The rest of the characters are limited to the following types of characters:
alphabetic (a .. z, A .. Z)
numeric (0 .. 9)
hyphen ("-")
underscore ("_")
You are using Formal Reference Notation as ${varName}
${{foo}} - so velocity try to get variable {foo} which is invalid VTL Identifier so it doesn't try to load the variable.
It probably then try to reference it as a JSON map {"a":"b"} and failed again, probably only { is accepted, so you remain with:
${{}
I tested your template in new velocity 2.0 and this issue isn't reproduce (in strict or non strict mode)
Output:
THis is ${{foo}} and this is bar.Hello and bar-Hello
So you have now a reason to upgrade to velocity 2.0.
(Question by John Williams, from a Coursera forum, which I decided to share with the community, since I haven't been able to find this answered anywhere.)
The following code runs without error:
int _j = 1;
//int 2var = 2;
int var2 = 2;
int Kvar = 3; // first letter can be uppercase
int spec$var = 4;
int com_pound_var = 5; // compounding without camel case
int com$pound$two = 6;
int $var = 199;
println(_j);
println(var2);
println(Kvar);
println(spec$var);
println(com_pound_var);
println(com$pound$two);
println($var); //first character can be special
Since the compiler accepts _j, Kvar, and $var as valid variable names, it is clear that variable names do not need to start with a lowercase letter.
I was unable to locate the variable naming rules anywhere in the reference.
What are the variable naming rules for the Processing language?
Quick answer: can start with any letter, underscore and dollar signs, continue with letters, numbers, underscore and dollar signs. Details below.
I could also not find anything in the reference or the documentation at all. However, inspecting the source code, I found that Processing is not a language of its own, but rather a framework in which you run some commands. The difference is that you're actually writing a different language, and Processing just gives you some basic scaffolding where you build on top of.
For some technical details: Processing compiles a Java Build with some flags, spins up a virtual machine (Java VM, not same thing as a full fledged virtual machine) and connects to it to get input and output streams (this is why you can interact with the mouse or get the console output of your own program in a separate window). (Source.)
This language, which you may have guessed already, is Java.
With that said, the actual docs that answer this question is the Java Language Specification, which, to simplify things, is as close as you can get to an answer. (But if you really want to know, it's a mess.)
Specifically, the section on Identifiers, which I'll sum up below:
Can start with any letter (A-Z, a-z), underscore (_), dollar sign ($), or any unicode "letter" (accented, chinese, etc. Details.)
Can continue with any of the above, and can also continue with digits (0-9). Can also contain other unicode "letters" (Details.)
Can have unlimited length
Cannot be any Java keyword (list here)
Cannot be false, true, null
They can look the same and still be different if their codes are different (some Unicode letters look just like letters but are different ones)
I hope this helps! Investigating was fun.
This question already has answers here:
Is there any language that allows spaces in its variable names [closed]
(2 answers)
Closed 9 years ago.
Related: Why can't variable names start with numbers?
Is there a technical reason why spaces aren't allowed in variable names or is it down to convention?
For example, what's stopping us from doing something like this?:
average score = sum of scores / number of scores
The only issue that comes to mind is keywords, but one could simply restrict the use of them in a variable name, and the lexer would be able to distinguish between part of a variable and a keyword.
There’s no fundamental reason, apart from the decisions of language designers and a history of single-token identifiers. Some languages in fact do allow multi-token identifiers: MultiMedia Fusion’s expression language, some Mac spreadsheet/notebook software whose name escapes me, and I’m sure of others. There are several considerations that make the problem nontrivial, though.
Presuming the language is free-form, you need a canonical representation, so that an identifier like account name is treated the same regardless of whitespace. A compiler would probably need to use some mangling convention to please a linker. Then you have to consider the effect of that on foreign exports—why C++ has the extern "C" linkage specifier to disable mangling.
Keywords are an issue, as you have seen. Most C-family languages have a lexical class of keywords distinct from identifiers, which are not context-sensitive. You cannot name a variable class in C++. This can be solved by disallowing keywords in multi-token identifiers:
if account age < 13 then child account = true;
Here, if and then cannot be part of an identifier, so there is no ambiguity with account age and child account. Alternatively, you can require punctuation everywhere:
if (account age < 13) {
child account = true;
}
The last option is to make keywords pervasively context-sensitive, leading to such monstrosities as:
IF IF = THEN THEN ELSE = THEN ELSE THEN = ELSE
The biggest issue is that juxtaposition is an extremely powerful syntactic construct, and you don’t want to occupy it lightly. Allowing multi-token identifiers prevents using juxtaposition for another purpose, such as function application or composition. Far better, I think, just to allow most nonwhitespace characters and thereby permit such identifiers as canonical-venomous-frobnicator. Still plenty readable but with fewer opportunities for ambiguity.
I think it is bacause the designers of the language have followed this convention.
I have searched on Google and found that while naming a variable this is a rule which is followed while naming a variable.
Some links are given below:-
SPSS notes
The following rules apply to variable names:
Variable names cannot contain spaces.
C Programming/Variables
Variable names by IBM
Java Variable Naming convention
Variable names are case-sensitive. A variable's name can be any legal
identifier — an unlimited-length sequence of Unicode letters and
digits, beginning with a letter, the dollar sign "$", or the
underscore character "". The convention, however, is to always begin
your variable names with a letter, not "$" or "". Additionally, the
dollar sign character, by convention, is never used at all. You may
find some situations where auto-generated names will contain the
dollar sign, but your variable names should always avoid using it. A
similar convention exists for the underscore character; while it's
technically legal to begin your variable's name with "_", this
practice is discouraged. White space is not permitted.
Wiki for Naming Convention
In all of the above links you will find that the designers have followed this naming convention for naming the variable.
Also check Is there any language that allows spaces in its variable names
This is forced from language designing.
Compiler needs to find out the meaning of words.
Compiler works on a "State Machine" method, and it needs to distinguish key words.
Maybe placing variable names in "[" and "]" give us some solution(like SQL).
But it will be harder to use it in coding...