I've just studied F# scripting, and I have a strange situation with changing variable in it:
let ParseActual (arg:string) = let mutable value = false
if arg.[1] = '-' then value <- false
else value <- true
if arg.[1] = '-' || arg.[1] = '+' then ref arg := arg.Remove(0,2)
else (
Console.WriteLine(arg)
ref arg := arg.Remove(0,1)
Console.WriteLine(arg)
)
AddActual(arg, value)
But it doesn't change the string. First output \r and second is the same \r. What's wrong removing some characters from string and assigning it a new value?
The arg string is immutable. What you can do is to use the string to create and return a new string with changed literal but you won't be able to mutate the existing string.
It's the case with all variables (not the most fortunate word, I know) in F#, once they are created and bound to a value they cannot be changed (unless you explicitly use the mutable keyword, as you did for the bool value).
Related
I'm using FloatArray:
private val values = FloatArray(5)
At some point, I need to reset each array value to zero. I tried doing it like this:
values.onEachIndexed { index, value -> value[index] = 0.0f }
But I am getting this error
No set method providing array access
At the same time, this code works (outside onEachIndexed) and I can set the value for the element:
values[1] = 4.0f
What am I doing wrong ? Please help me
Your attempt does not work because value there represents an element of the array, not the array itself, so you cannot use [] to set it. Reassigning it a new value will not work either, because value is a lambda parameter.
There is a builtin method for filling the entirety (or a portion) the array - fill
values.fill(0.0f)
const a: string = "abc";
const b: string[] = ["def", "ghi"];
const c = a + b
produces abcdef,ghi comma separated string of items in string[]. How to let typescript know this should not be allowed in first place?
c = a + b is actually {} + \[\]
{} + []
The {} here is not parsed as an object, but instead as an empty block (§12.1, at least as long as you're not forcing that statement to be an expression, but more about that later). The return value of empty blocks is empty, so the result of that statement is the same as +[]. The unary + operator (§11.4.6) returns ToNumber(ToPrimitive(operand)). As we already know, ToPrimitive([]) is the empty string, and according to §9.3.1, ToNumber("") is 0.
a is string which is {} side and b (string[]) is []. When you sum string object with array of string, javascript implicitly converts array of string to concatenated string (Which is expected behavior)
so, there is nothing illegal to javascript here.
I have an array and I first check if the array has the index of given number. I like to assign a value at that index if the array has not got any.
var newArray:Array = [0,1,2,3];//length is 4
if(newArray[5] == "")//true
{
newArray[5] = 5;
}
Adobe Help page says;
Inserting array elements
...
If the Array or Vector doesn’t already have an element at that index, the index is created and the value is stored there. If a value exists at that index, the new value replaces the existing one.
But I am not sure it is about null elements or undefined.
How can I assign a value to index that doesn't exist?
I can push till the given index but wondering is anything else possible.
array reference its elements as not typed so if an element does not exist it can be only undefined (default value for untyped) so in your case no need to check for null or "", you only need to check for undefined.
if(newArray[5] == undefined)
{
newArray[5] = 5;
}
EDIT:
undefined is a keyword in as3 that defines a default value for untyped objects. It is the value you use to check if an untyped object has no current value. (As opposed to a typed object that has null as default value with the exception of numbers).
Using "" as you suggest doesn't work since it is a valid String value and would only work to check if a String object is not null and has a length of 0. Equivalent of String.length == 0.
The assignment is correct, even though the index 4 does not exist at this point the Array Object does not complain and assign the value to index 5.
Writing a C extension for a Ruby gem, I need to test a parameter value for equality with a known symbol and string.
I realize you can intern a string with
char *foo = "foo";
VALUE foo_string_value = rb_intern(foo);
and then convert it into a symbol:
VALUE foo_sym_value = ID2SYM(foo_string_value);
My question is whether I can now reliably test the parameter, which may be a symbol or string, :foo or 'foo', with these using C pointer equality:
if (param == foo_string_value || param == foo_sym_value) {
...
}
In other words, does the interning guarantee that pointer equality is also value equality for symbols and strings?
If this is the wrong approach, then what's the right one to do this comparison?
I figured this out. A reasonable way to do what I want appears to be
VALUE square_sym = ID2SYM(rb_intern("square"));
VALUE kind_as_sym = rb_funcall(kind_value, rb_intern("to_sym"), 0);
if (square_sym == kind_as_sym) {
...
}
Symbols are always interned and have unique values. Strings aren't and don't. They can be interned to get IDs that are integers unique for each string, but that doesn't help in this case.
Is it fine to display the output of Array.toString() to the user, or is there a possibility that the string format could change in future versions of ActionScript 3 or other compilers?
Here's an excerpt describing Array.toString from ECMA-262, which ActionScript 3 follows very closely:
15.4.4.2
Array.prototype.toString ( ) When the toString method is called, the following steps are taken:
1. Let array be the result of calling ToObject on the this value.
2. Let func be the result of calling the [[Get]] internal method of array with argument "join".
3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.
And Array.join:
15.4.4.5
Array.prototype.join (separator) The elements of the array are converted to Strings, and these Strings are then concatenated, separated by occurrences of the separator. If no separator is provided, a single comma is used as the separator. The join method takes one argument, separator, and performs the following steps:
1. Let O be the result of calling ToObject passing the this value as the argument.
2. Let lenVal be the result of calling the [[Get]] internal method of O with argument "length".
3. Let len be ToUint32(lenVal).
4. If separator is undefined, let separator be the single-character String ",".
5. Let sep be ToString(separator).
6. If len is zero, return the empty String.
7. Let element0 be the result of calling the [[Get]] internal method of O with argument "0".
8. If element0 is undefined or null, let R be the empty String; otherwise, Let R be ToString(element0).
9. Let k be 1.
10. Repeat, while k < len
a. Let S be the String value produced by concatenating R and sep.
b. Let element be the result of calling the [[Get]] internal method of O with argument ToString(k).
c. If element is undefined or null, Let next be the empty String; otherwise, let next be ToString(element).
d. Let R be a String value produced by concatenating S and next.
e. Increase k by 1.
11. Return R.
So, the default behavior is very well defined, and won't change.
It is safe to use it as it is. Array.toString() has been the same since AS3 came out.
Return value of Array.toString() is by now equal to that of Array.join().
If you are that concerned about this behaviour not changing, use Array.join() (or, to be completely pedantic, Array.join(',')) explicitly, and you'll be safe. Joining array works this way since ActionScript exists and it's absolutely unlikely that Adobe will change something to it and loose backwards compatibility (and, well, sanity).