I have a Golang template, defined like this
{{- define "test" -}}
{{- printf "%s" .Name | trunc 24 -}}
{{- end -}}
Then I use it in one of my files:
{{ template "test" . }}
What does the dot mean after "test"? Golang template docs say:
{{template "name" pipeline}}
The template with the specified name is executed with dot set
to the value of the pipeline.
But I am not sure what pipeline is. Reading documentation gave no results, could anyone explain once again?
Also, why do we have to start values beginning with dot? E.g. {{ - printf "%s" .Name | trunc 24 -}}. Is it also a kind of pipeline?
Thank you in advance!
There are 2 template packages, text/template and html/template.
They have the same interface, but the html/template package is for generating HTML output safe against code injection, and should be used instead of text/template whenever the output is HTML.
Since they have the same interface but the html/template provides some extra functionality (contextual escaping of the inserted data), the basics and principles are only documented at text/html, and the documentation of html/template mostly focuses on detailing the extra.
That being said, "pipeline" belongs to the basics. It is documented in text/template, section Pipelines:
Pipelines
A pipeline is a possibly chained sequence of "commands". A command is a simple value (argument) or a function or method call, possibly with multiple arguments:
Argument
The result is the value of evaluating the argument.
.Method [Argument...]
The method can be alone or the last element of a chain but,
unlike methods in the middle of a chain, it can take arguments.
The result is the value of calling the method with the
arguments:
dot.Method(Argument1, etc.)
functionName [Argument...]
The result is the value of calling the function associated
with the name:
function(Argument1, etc.)
Functions and function names are described below.
A pipeline may be "chained" by separating a sequence of commands with pipeline characters '|'. In a chained pipeline, the result of each command is passed as the last argument of the following command. The output of the final command in the pipeline is the value of the pipeline.
"Arguments" and "pipelines" are evaluations of data.
The "dot" . is basically a cursor, pointing to somewhere in the data structure you pass when executing the template. The starting value of the dot is the value you pass, but this dot is modified by many actions, such as {{range}} or {{with}}.
Execution of the template walks the structure and sets the cursor, represented by a period '.' and called "dot", to the value at the current location in the structure as execution proceeds.
So when you write .Name, that means that the value where dot is pointing currently, you want to refer to its field or method or key called Name. For example if you pass a struct, at the beginning of your template .Name will denote the struct field Name if it exists, or its method named Name().
When you invoke / include another template, you have the possibility to tell what value you what to pass to its execution. When you write {{template "something" .}}, that means you want to pass the value currently pointed by dot to the template execution. If you want to pass only the Name field of the struct pointed by the dot, you may do it like {{template "something" .Name}}.
The value you pass as the pipeline in {{template}} will become the dot inside the invoked other template.
So as your template is being processed / rendered, the dot may be changed and point "only" to a part of the value originally passed to your template execution. Often it's handy or required to still reach the original value and not just the cursor. For this the template package provides the $:
When execution begins, $ is set to the data argument passed to Execute, that is, to the starting value of dot.
So even if you're inside a {{range}} for example (which sets the dot to the successive elements of the array / slice / map you're ranging over), you can still reach out and refer to any other parts of the value passed to the template execution.
So for example if you're ranging over a slice of books like {{range .Books}}, and if you need the Name field of the originally passed struct, you may do it inside {{range}} like this:
{{range .Books}}
Title: {{.Title}}
Original name: {{$.Name}}
{{end}}
Related
BigQuery describes a path_expression in the Syntax page as follows:
A path expression describes how to navigate to an object in a graph of objects and generally follows this structure...
Examples:
foo.bar
foo.bar/25
foo/bar:25
foo/bar/25-31
/foo/bar
/25/foo/bar
What are some actual examples of a Path Expression with a valid table, for example in a CTE? My thinking was that a path expression would be something that explicitly qualifies a field or struct sub-field, such as:
myTable.myField.mySubfield
But from the above syntax, which allows for:
/:-
I'm not exactly sure what it is or how it would be used. Could someone show a real-world example of how a path expression would be used?
Path expressions describe where to search for (or store) data. Consider this example from the docs:
#legacySQL
SELECT
weight_pounds, state, year, gestation_weeks
FROM
[bigquery-public-data:samples.natality]
ORDER BY
weight_pounds DESC
LIMIT
10;
In this example, the portion [bigquery-public-data:samples.natality] is the path_expression.
It is saying to look at the natality table in the samples database in the bigquery-public-data project.
But from the above syntax, which allows for: /:-
This would actually not be allowed, as a path_expression.
This example would be parsed as:
/:-
{first_part}/{subsequent_part}:{subsequent_part}
{{ unquoted_identifier | quoted_identifier }} /
{{ unquoted_identifier | quoted_identifier | number }} :
{{ unquoted_identifier | quoted_identifier | number }}
An unquoted_identifier must at least begin with a letter or an underscore. A quoted_identifier can contain any character, but cannot be empty. The empty string therefore cannot be considered an unquoted_identifier, quoted_identifier, or number, so this expression is invalid (and is invalid in 3 positions).
A possible minimal path_expression could be something like:
a:b.c
meaning look in the c table in the b database in the a project.
I can be wrong, but I think you are confusing Path Expression (as it is defined in referenced documentation) with something like (for example) JSONPath.
In my mind, the the former is just terminology that introduced in order to have consistent reference within the documentation, while later (obviously) is query language for JSON, similar to XPath for XML, etc.
So, if you would asked for something like JSONPath use - I bet you would get tones of usage examples, but asking about Path Expression use has not much chances to gather answers even having hefty bounty as it is ONLY used in that documentation.
I have an outgoing web service to send data from Siebel 7.8 to an external system. In order for the integration to work, before I send the data, I must change one of the field values, replacing every occurence of "old" with "new". How can I do this with EAI data mappings?
In an ideal world I would just use an integration source expression like Replace([Description], "old", "new"). However Siebel is far from ideal, and doesn't have a replace function (or if it does, it's not documented). I can use all the Siebel query language functions which don't need an execution context. I can also use the functions available for calculated fields (sane people could expect both lists to be the same, but Siebel documentation is also far from ideal).
My first attempt was to use the InvokeServiceMethod function and replace the text myself in eScript. So, this is my field map source expression:
InvokeServiceMethod('MyBS', 'MyReplace', 'In="' + [Description] + '"', 'Out')
After some configuration steps it works fine... except if my description field contains the " character: Error parsing expression 'In="This is a "test" with quotes"' for field '3' (SBL-DAT-00481)
I know why this happens. My double quotes are breaking the expression and I have to escape them by doubling the character, as in This is a ""test"" with quotes. However, how can I replace each " with "" in order to call my business service... if I don't have a replace function? :)
Oracle's support web has only one result for the SBL-DAT-00481 error, which as a workaround, suggests to place the whole parameter inside double quotes (which I already had). There's a linked document in which they acknowledge that the workaround is valid for a few characters such as commas or single quotes, but due to a bug in Siebel 7.7-7.8 (not present in 8.0+), it doesn't work with double quotes. They suggest to pass instead the row id as argument to the business service, and then retrieve the data directly from the BC.
Before I do that and end up with a performance-affecting workaround (pass only the ID) for the workaround (use double quotes) for the workaround (use InvokeServiceMethod) for not having a replace function... Am I going crazy here? Isn't there a simple way to do a simple text replacement in a Siebel data mapping?
first thing (quite possibly - far from optimal one) which is coming to my mind - is to create at source BC calculated field, aka (NEW_VALUE), which becomes "NEW" for every record, where origin field has a value "OLD". and simply use this field in integration map.
I'm using Doxygen to document C++ code, and am writing a substantial amount of Doxygen doc for the code. In one place I'm making a list of groups in the code, and would like it to appear as follows:
Control Module: the module that controls everything
Slave Module: the module that is the slave of the Control Module
My documentation source looks like this:
- #ref CM: the module that controls everything
- #ref SM: the module that is the slave of the #CM
But, problem: Doxygen seems to be reading the reference name as CM:, not CM, and thus can't find the reference. So, somehow I need to tell Doxygen where the reference name ends. (For example, if I were using Bash, and wanted to echo a variable string with an "s" as a suffix, I'd use echo "${NOUN}s".)
As a workaround, I could add a space between the name and the subsequent colon, but that makes the resulting doc harder to read and I'd like to avoid it.
Under Special Commands, the Doxygen manual includes the following hopeful-sounding information:
Some commands have one or more arguments. Each argument has a certain
range:
If <sharp> braces are used the argument is a single word.
If (round) braces are used the argument extends until the end of the line on
which the command was found.
If {curly} braces are used the argument
extends until the next paragraph. Paragraphs are delimited by a blank
line or by a section indicator.
OK, that's all fine and good, but the documentation doesn't say, and I can't figure out, where those braces are supposed to go. Around the argument alone? Around the entire command and argument? Neither works, and I can't come up with an alternative that does work.
So, how do I indicate the end of a reference name to Doxygen? And if braces are the answer, where do they go?
This works for Doxygen version 1.8.11:
\ref name "":
Apparently, the empty string triggers a fall-back to use the name argument before it.
The Doxygen documentation you quote is describing the syntax of the Doxygen documentation, not of sources to be parsed by your use of Doxygen.
In other words, if <sharp> braces are used when describing a command, it takes a single word; and so on.
Looking at the documentation of #ref:
\ref <name> ["(text)"]
The name argument is in "sharp braces," and so it's just a single word. Unfortunately, Doxygen seems to interpret : as part of that word. Your best bet would be to introduce a space:
#ref CM : the ...
You could also try whether a zero-width character would break the word recognition:
#ref CM: the ...
I have encountered problem in yaml-cpp parser. When I try to load following definition:
DsUniversity:
university_typ: {type: enum, values:[Fachhochschule, Universitat, Berufsakademie]}
students_at_university: {type: string(50)}
I'm getting following error:
Error: yaml-cpp: error at line 2, column 39: end of map flow not found
I tried to verify yaml validity on http://yaml-online-parser.appspot.com/ and http://yamllint.com/ and both services reports yaml as valid.
Problem is caused by missing space after "values:" definition. When yaml is updated to following format:
DsUniversity:
university_typ: {type: enum, values: [Fachhochschule, Universitat, Berufsakademie]}
students_at_university: {type: string(50)}
everything works as expected.
Is there any way how to configure/update/fix yaml-cpp parser to proceed also yamls with missing space after colon?
Added:
It seems that problem is caused by requirement for empty char as separator. When I simplified testing snippet to
DsUniversity:[Fachhochschule, Universitat, Berufsakademie]
yaml-cpp parser reads it as one scalar value "DsUniversity:[Fachhochschule, Universitat, Berufsakademie]". When empty char is added after colon, yaml-cpp correctly loads element with sequence.
yaml-cpp is correct here, and those online validators are incorrect. From the YAML 1.2 spec:
7.4.2. Flow Mappings
Normally, YAML insists the “:” mapping value indicator be separated from the value by white space. A benefit of this restriction is that the “:” character can be used inside plain scalars, as long as it is not followed by white space. This allows for unquoted URLs and timestamps. It is also a potential source for confusion as “a:1” is a plain scalar and not a key: value pair.
...
To ensure JSON compatibility, if a key inside a flow mapping is JSON-like, YAML allows the following value to be specified adjacent to the “:”. This causes no ambiguity, as all JSON-like keys are surrounded by indicators. However, as this greatly reduces readability, YAML processors should separate the value from the “:” on output, even in this case.
In your example, you're in a flow mapping (meaning a map surrounded by {}), but your key is not JSON-like: you just have a plain scalar (values is unquoted). To be JSON-like, the key needs to be either single- or double-quoted, or it can be a nested flow sequence or map itself.
In your simplified example,
DsUniversity:[Fachhochschule, Universitat, Berufsakademie]
both yaml-cpp and the online validators parse this correctly as a single scalar - in order to be a map, as you intend, you're required a space after the :.
Why does YAML require that space?
In the simple plain scalar case:
a:b
could be ambiguous: it could be read as either a scalar a:b, or a map {a: b}. YAML chooses to read this as a scalar so that URLs can be easily embedded in YAML without quoting:
http://stackoverflow.com
is a scalar (like you'd expect), not a map {http: //stackoverflow.com}!
In a flow context, there's one case where this isn't ambiguous: when the key is quoted, e.g.:
{"a":b}
This is called JSON-like because it's similar to JSON, which requires quotes around all scalars. In this case, YAML knows that the key ends at the end-quote, and so it can be sure that the value starts immediately.
This behavior is explicitly allowed because JSON itself allows things like
{"a":"b"}
Since YAML 1.2 is a strict superset of JSON, this must be legal in YAML.
I think it would be beneficial to parse scalar/keys differently immediately inside a flow map{, if you agree, vote here please.
https://github.com/yaml/yaml-spec/issues/267
I have a large codebase, where we need to make a pattern-change in the argument of a specific function.
i.e. All arguments to a function foo() are renamed from the format something.anotherThing are to be renamed as something_anotherThing
The arguments can be anything but will always be in a str1.str2 format. It is to be done for arguments of this one function only, all other code should remain untouched.
e.g.
foo(a.x) --> foo(a_x)
foo(a4.b6) --> foo(a4_b6)
Is there any way I can achieve it using regular expression or a tool, where i can do this in one step for all the files, for one specific function?
If the function would have only one argument, it would be easy:
Use a tool that is able to search and replace in multiple files, eg. TextCrawler.
And than select the regular expression tab and fill in:
RegExp:
(foo\([^)]+)(\.)([^)]+\))
Replace:
$1_$3
This will not work, if there are more arguments in the function. But you can click the "Replace" button again and then again until it says that no result was found. You will have to do it maximum n-times, where n = max number of arguments in any function.