How do I transform existing log statements into interpolated string format? - string

I want to change existing statements such as
log.debug("Value of foo : {}", foo)
to use interpolated string format instead
log.debug(s"Value of foo : $foo")
Although IntelliJ has a blog post on converting between string formats, it seems to require having to first convert the existing string to
"Value of foo ".format(foo)
which defeats the purpose of wanting an automatic format change option in the first place (and doesn't work properly for me anyway).
How can I easily format these log statements to use string interpolation? Is there any way to do so wholesale (across an entire project)?

In IntelliJ, you can do Inspect Code (right click -> Analyze -> Inspect Code). Make sure to turn on Legacy String Formatting rule in your Inspection Profile. I think this rule is part of the Scala plugin.
If you turn on this rule, you can make it a warning, error, or some other options. You can always hit alt + enter while your cursor is on a statement with string concatenation and then select convert to interpolated string from the dropdown.

Related

How can I store a format string template outside of my source code?

When translating, messages can be in different languages and have format parameters. I want to be able to do this where the template can be stored in a file:
static PATTERN: &'static str = r"Hello {inner};";
/// in some implementation
fn any_method(&self) -> String {
format!(PATTERN, inner = "world");
}
That's not possible. Format strings must be actual literal strings.
The next best approach would be some kind of dynamic string format library. Or, failing that, you could always use str::replace if your needs aren't too complex.
This is definitely possible and trivial to do using the include_str macro that has been available in the standard library since version 1.0.0. The following example was tested with rustc 1.58.1:
Contents of src/main.rs:
println!(include_str!("src/hello-world.tmpl"), "world");
Contents of src/hello-world.tmpl
Hello {inner}
This works because include_str injects the contents of the template file as a string literal before println, format, and friends have a chance to evaluate their arguments. This approach only works when the format template you want to include is available during macro expansion - like it is in your example. If it's not, then you should consider other options like the ones suggested by #DK.
As an added bonus: You can also define format strings in source code locations other than the site where they are used by defining them as macros.

Using tab as delimiter in tFileInputDelimited component in Talend Open Studio

I have written an ETL in Talend Open Studio that loads a CSV/TSV file in a database. To do so, I want to provide the delimiter in tFileInputDelimited component using dynamic context load from a text file. I have specified it in the context file as fieldDelimiter="\t" and in the tFileInputDelimited component as shown in the screenshot. But, it doesn't work as a delimiter. I have also tried using fieldDelimiter="\\t" or fieldDelimiter="\u0009" (unicode character for tab).
What should I provide in the context file so that the delimiter is a tab character and not "\t" string as is happening in this case?
I notice a difference in the context variable names. In the screen shot you have mentioned (String)context.get("fileDelimiter"). But in the text you are saying "I have specified it in the context file as fieldDelimiter="\t" ".
just keeping the context as follows in the .properties file should work
fieldDelimiter=\t
Also use context.fieldDelimiter instead of (String)context.get("fileDelimiter").
In your context file, just put fileDelimiter = \t
(Without quotes)
And then access the variable in field delimiter. Talend will automatically handle it as string.
Hope this works.
There is no function (String)context.get("key") that I know of. If you have set the separator as a String element in the Context, just access it directly. Now there will be an empty String set as the field separator I suppose.
So if your field is called fileDelimiter simply put context.fileDelimiter into the Field Separator.
As pointed out by others, you should use context.ParamName syntax, the benefit of this method is syntax checking at compile time which eliminates the risk of typos in your variable names.
This parameter must be declared in your job (contexts tab) in order for Talend to recognize it. You can either create it as a built-in or import it if it's in the repository.

SSRS - How to get a part of a string

I have a parameter called Analyst group in this format :
[Dimension].[Analyst Group].&[Nl.Workplace.Foundation]
I want to pass this parameter to another report, to filter data. Its a multi value parameter. But the other report only accepts it in this format : [KanBan].[Analyst Group].&[Nl.Workplace.Foundation]
So im trying to isolate the "Nl.Workplace.Foundation", so i can do the following thing in the Go To Report parameter expression :="[KanBan].[Analyst Group].&["& --Isolated analyst group-- &"]" to create the desired format.
So what i need is to extract the part between .&[ and ]
But i really have no idea how to isolate that part of the string.
Found a solution! If i just use the Parameter.label instead of Parameter.value it automatically does what i want!
A different solution has been found, but I will still answer the initial question. It could help.
So what i need is to extract the part between .&[ and ]
You could use a regex.
This may not be the fastest way but it can handle most of the situations.
So let's assume you have a string containing:
[Dimension].[Analyst Group].&[Nl.Workplace.Foundation]
And you want to get the following string:
Nl.Workplace.Foundation
Just use the following expression:
=System.Text.RegularExpressions.Regex.Match("[Dimension].[Analyst Group].&[Nl.Workplace.Foundation]", "\.&\[(?<NWF>[^]]+)\]").Groups("NWF").Value
In the expression, replace the input string with your dynamic values, like for example:
=System.Text.RegularExpressions.Regex.Match(Fields!Dimension.Value & "." & Fields!AnalystGroup.Value, "\.&\[(?<NWF>[^]]+)\]").Groups("NWF").Value
I'm keeping the formula as simple as possible so that you can easily adapt it, with, say, handling the case where an input string will not have a match (with the above query it will return #Error).
You could do this by adding an IIF() or better, use a custom function that you can reuse in several places and will reduce the length of your expression.

Get argument names in String Interpolation in Scala 2.10

As of scala 2.10, the following interpolation is possible.
val name = "someName"
val interpolated = s"Hello world, my name is $name"
Now it is also possible defining custom string interpolations, as you can see in the scala documentation in the "Advanced usage" section here http://docs.scala-lang.org/overviews/core/string-interpolation.html#advanced_usage
Now then, my question is... is there a way to obtain the original string, before interpolation, including any interpolated variable names, from inside the implicit class that is defining the new interpolation for strings?
In other words, i want to be able to define an interpolation x, in such a way that when i call
x"My interpolated string has a $name"
i can obtain the string exactly as seen above, without replacing the $name part, inside the interpolation.
Edit: on a quick note, the reason i want to do this is because i want to obtain the original string and replace it with another string, an internationalized string, and then replace the variable values. This is the main reason i want to get the original string with no interpolation performed on it.
Thanks in advance.
Since Scala's string interpolation can handle arbitrary expressions within ${} it has to evaluate the arguments before passing them to the formatting function. Thus, direct access to the variable names is not possible by design. As pointed out by Eugene, it is possible to get the name of a plain variable by using macros. I don't think this is a very scalable solution, though. After all, you'll lose the possibility to evaluate arbitrary expressions. What, for instance, will happen in this case:
x"My interpolated string has a ${"Mr. " + name}"
You might be able to extract the variable name by using macros but it might get complicated for arbitrary expressions. My suggestions would be: If the name of your variable should be meaningful within the string interpolation, make it a part of the data structure. For example, you can do the following:
case class NamedValue(variableName: String, value: Any)
val name = NamedValue("name", "Some Name")
x"My interpolated string has a $name"
The objects are passed as Any* to the x. Thus, you now can match for NamedValue within x and you can do specific things depending on the "variable name", which now is part of your data structure. Instead of storing the variable name explicitly you could also exploit a type hierarchy, for instance:
sealed trait InterpolationType
case class InterpolationTypeName(name: String) extends InterpolationType
case class InterpolationTypeDate(date: String) extends InterpolationType
val name = InterpolationTypeName("Someone")
val date = InterpolationTypeDate("2013-02-13")
x"$name is born on $date"
Again, within x you can match for the InterpolationType subtype and handle things according to the type.
It seems that's not possible. String interpolation seems like a compile feature that compiles the example to:
StringContext("My interpolated string has a ").x(name)
As you can see the $name part is already gone. It became really clear for me when I looked at the source code of StringContext: https://github.com/scala/scala/blob/v2.10.0/src/library/scala/StringContext.scala#L1
If you define x as a macro, then you will be able to see the tree of the desugaring produced by the compiler (as shown by #EECOLOR). In that tree, the "name" argument will be seen as Ident(newTermName("name")), so you'll be able to extract a name from there. Be sure to take a look at macro and reflection guides at docs.scala-lang.org to learn how to write macros and work with trees.

ABAP startRFC.exe UTF-8 diacritics text transfer

I have a function module (FM) in SAP and I call it externally using startRFC. The only output of FM is one internal table. This table has only 1 column of type char(100) and I need to get it to text file. StartRFC works well, but if there is diacritics (for example Czech language: ěščřžýáíé) instead of these characters only hashes # appear.
Have someone ever solved similar issue?
If I call the same algorithm manually and write strings on screen in SAP, everything is ok. But startRFC somehow destroys it. The problem may be in the data transfer between SAP and startRFC. But I don't know how this transfer works.
I found a solution but it is terribly slow. It converts string to hexadecimal string using "gcl_conv_to_x->write" and "gcl_conv_to_x->get_buffer" than calls "SCMS_XSTRING_TO_BINARY" and you need a binary table. But it takes 5minutes to do all this stuff. Without this conversion my algorithm takes 15 seconds.
So finally a solution...
You need to create XSTRING variable and fill it with your text. To convert STRING to XSTRING use FM: SCMS_STRING_TO_XSTRING.
Then you will need an internal table with row type BAPICONTEN. It already contains component (column) of type SDOK_SDATX (RAW 1022).
And you just append a new line to this table like this:
data: my_table_row LIKE LINE OF my_table.
my_table_row-line = my_xstring.
APPEND my_table_row INTO my_table.
This table (my_table) can be returned via RFC and will contain Cyrillic, German characters etc..
I am just a beginner, so do not ask me how to create the table, please :)

Resources