Does + operator behave like stringbuilder in JDK 7 ?
In terms of creating a string, does it create new immutable strings or appends to the same object ? Is it the same/different in terms of performance as well ?
Does + operator behave like stringbuilder in JDK 7 ?
There is an optimization that will automatically turn String concatenations into StringBuilders (in some cases).
In terms of creating a string, does it create new immutable strings or
appends to the same object ?
If you have a bunch of data strung together with +, it will create a new immutable String literal:
System.err.println("" + 5 + " hello foobar" + "...");
Related
On every site that talks about VBScript, the '&' operator is listed as the string concatenation operator. However, in some code that I have recently inherited, I see the '+' operator being used and I am not seeing any errors as a result of this. Is this an accepted alternative?
The & operator does string concatenation, that is, forces operands to be converted to strings (like calling CStr on them first). +, in its turn, forces addition if one of the expressions is numeric. For example:
1 & 2
gives you 12, whereas
1 + 2
"1" + 2
1 + "2"
give you 3.
So, it is recommended to use & for string concatenation since it eliminates ambiguity.
The + operator is overloaded, whereas the & operator is not. The & operator only does string concatenation. In some circles the & operator is used as a best practice because it is unambiguous, and therefore cannot have any unintended effects as a result of the overloading.
+ operator might backfire when strings can be interpreted as numbers. If you don't want nasty surprises use & to concatenate strings.
In some cases the + will throw an exception; for example the following:
Sub SimpleObject_FloatPropertyChanging(fvalue, cancel)
'fvalue is a floating point number
MsgBox "Received Event: " + fvalue
End Sub
You will get an exception when the COM object source fires the event - you must do either of the following:
MsgBox "Received Event: " & fvalue
or
MsgBox "Received Event: " + CStr(fvalue)
It may be best in either case to use CStr(value); but using & per above comments for string concatenation is almost always best practice.
In the string
"#{x ? (x.to_s + ' is ') : ''}ok", Rubocop's Style/StringConcatenation suggests avoiding the +.
But that requires a nested string interpolation
"#{x ? '#{x.to_s} is ' : ''}ok)",
which at least in Ruby 2.7 is not expanded: #{x.to_s} is treated like any other literal.
Is the + version alright because it's on the fringes of what a style guide could cover, or must one introduce a temporary variable?
tmp = x ? '#{x.to_s} is ' : ''
"#{tmp}ok"
Context: the string is sent to a logfile. ok is actually a long list of details. x is worth logging, but only when it exists.
Yes, a variable will make this more readable (imo):
prefix = "#{x} is " if x
"#{prefix}ok"
(this relies on the fact that nil#to_s == '')
Given that "ok" is actually:(according to the comments)
"...a long string that has even more interpolations. Duplicating that string isn't DRY".
I would go with
ok = generate_some_long_string()
ok.prepend("#{x} is ") if x
ok
This does mutate ok but based on my understanding of the question this may actually be desirable.
Nesting Interpolation
As an aside and I would not recommend it (because it is difficult to read) but nesting interpolation is completely valid ruby e.g.
x="val"
"#{x ? "#{x} is " : ""}ok"
#=> "val is ok"
This works because what is inside the interpolation closure is treated like any other ruby code. The inner double quotes open and close a new String rather than closing the first and opening another because the interpolation closure is waiting for a closing curly brace. You could technically do this at any depth.
"#{x ? "#{"the #{y = x}ue of"} #{x} is " : ""}#{y.inspect}"
#=> "the value of val is \"val\""
I am wondering how to make something where if X=5 and Y=2, then have it output something like
Hello 2 World 5.
In Java I would do
String a = "Hello " + Y + " World " + X;
System.out.println(a);
So how would I do that in TI-BASIC?
You have two issues to work out, concatenating strings and converting integers to a string representation.
String concatenation is very straightforward and utilizes the + operator. In your example:
"Hello " + "World"
Will yield the string "Hello World'.
Converting numbers to strings is not as easy in TI-BASIC, but a method for doing so compatible with the TI-83+/84+ series is available here. The following code and explanation are quoted from the linked page:
:"?
:For(X,1,1+log(N
:sub("0123456789",ipart(10fpart(N10^(-X)))+1,1)+Ans
:End
:sub(Ans,1,length(Ans)-1?Str1
With our number stored in N, we loop through each digit of N and store
the numeric character to our string that is at the matching position
in our substring. You access the individual digit in the number by
using iPart(10fPart(A/10^(X, and then locate where it is in the string
"0123456789". The reason you need to add 1 is so that it works with
the 0 digit.
In order to construct a string with all of the digits of the number, we first create a dummy string. This is what the "? is used
for. Each time through the For( loop, we concatenate the string from
before (which is still stored in the Ans variable) to the next numeric
character that is found in N. Using Ans allows us to not have to use
another string variable, since Ans can act like a string and it gets
updated accordingly, and Ans is also faster than a string variable.
By the time we are done with the For( loop, all of our numeric characters are put together in Ans. However, because we stored a dummy
character to the string initially, we now need to remove it, which we
do by getting the substring from the first character to the second to
last character of the string. Finally, we store the string to a more
permanent variable (in this case, Str1) for future use.
Once converted to a string, you can simply use the + operator to concatenate your string literals with the converted number strings.
You should also take a look at a similar Stack Overflow question which addresses a similar issue.
For this issue you can use the toString( function which was introduced in version 5.2.0. This function translates a number to a string which you can use to display numbers and strings together easily. It would end up like this:
Disp "Hello "+toString(Y)+" World "+toString(X)
If you know the length of "Hello" and "World," then you can simply use Output() because Disp creates a new line after every statement.
So I have a string called borrowed_book_bitmask and I want to pad this string with another string both on the left and right. The padding is defined in some class as a constant. So I have
borrowed_book_bitmask = Module1::Model1::BITMASK_PADDING + borrowed_book_bitmask + Module1::Model1::BITMASK_PADDING
This syntax is a bit clunky and inelegant. Is there a better, more succinct way to express the above?
Assume I can't change the variable name and constant name.
You can use the center method
a = "abc"
"abc.center(a.size + 4 * 2)
=> " abc "
borrowed_book_bitmask.gsub! /\A|\z/, Module1::Model1::BITMASK_PADDING
What do you mean by "pad"? Always adding the same strings on each side?
"#{Module1::Model1::BITMASK_PADDING}#{borrowed_book_bitmask}#{Module1::Model1::BITMASK_PADDING"}
What do you mean by "elegant"? Interpolation is vaguely more elegant than concatenation (and more performant IIRC, which I might not). If borrowed_book_bitmask is a method then you could embed this in a method, or use a decorator to encapsulate the functionality.
It seems to me that the inelegance comes from the repetition of the module parameter; I keep having to visually parse two long terms to check that they are the same.
pad = Module1::Model1::BITMASK_PADDING
borrowed_book_bitmask = pad + borrowed_book_bitmask + pad
...too obvious? Maybe that's only more elegant for me.
I want to extract the quoted substrings from inside a string. This is an example:
string = 'aaaa' + string_var_x + 'bbbb' + string_var_y
The output after parsing should be:
["'aaaa'", "'bbbb'"]
The initial solution was to string.scan /'\w'/ which is almost ok.
Still I can't get it working on more complex string, as it's implied that inside '...' there can be any kind of characters (including numbers, and !##$%^&*() whatever).
Any ideas?
I wonder if there's some way to make /'.*'/ working, but make it less greedy?
Lazy should fix this:
/'.*?'/
Another possibility is to use this:
/'[^']*'/
An alternate way to do it is:
>> %{string = 'aaaa' + string_var_x + 'bbbb' + string_var_y}.scan(/'[^'].+?'/)
#=> ["'aaaa'", "'bbbb'"]
String.scan gets overlooked a lot.