When could the user's Locale.current.region be nil? - ios

The locale region is optional from Foundation. It is my understanding that this property is read from the device under iOS Settings > General > Language & Region > Region.
What is the possible scenarios that the region property is nil; why is it optional?

It is my understanding that this property is read from the device under iOS Settings > General > Language & Region > Region
Well, that would be Locale.current, but that is not the only instance of Locale instance there can be. You can create your own locales.
More accurately, region is:
This property corresponds to the rg key of the Unicode BCP 47 extension.
For locale instances created with the rg specifier (such as en-GB#rg=US), or with a custom Locale.Components, this property represents the custom region. Otherwise, it represents the language’s region.
I tried setting Locale.Components.region to nil, but the Locale created this way still has the default region of the language:
var components = Locale.Components(languageCode: .english)
components.region = nil
let locale = Locale(components: components)
print(locale.region) // US
If the Locale.Language does not belong to any region though, then region would be nil. And such Locale.Languages do exist! For example:
// zxx - no linguistic content
let unidentified = Locale(languageCode: .unidentified)
print(unidentified.region) // nil
// mul - multiple languages
let multiple = Locale(languageCode: .multiple)
print(multiple.region) // nil
So region has to be optional at least because of the mul and zxx "languages", as required in BCP 47.

Related

Pass an empty value to an OData V2 Edm.Time property

I have a variable type time but sometimes this variable doesn't have anything.
When it is initial, it shouldn't be "000000", I want an empty value without anything (no zeros). Let me explain my problem with the code:
IF lwa_hora IS INITIAL.
CLEAR lwa_hora.
ls_entity-hora = lwa_hora. " Result: 000000 but I don't want any zero
ELSE.
ls_entity-hora = lwa_hora. " Result: 000000
ENDIF.
I tried with CLEAR but nothing happens.
I need this is because in the JavaScript frontend client logic, I need the OData property to contain a falsy value (E.g. null or an empty string "").
But it always has the value "000000" which is not an empty string. Is it possible to make something in the backend to "clear" the variable?
The time data-type in abap (t) is a value-type. It's internally implemented as an integer counting the seconds since midnight. 0 seconds since midnight is a valid value, so it can't have a null-value.
However, ABAP allows you to create a reference to any value-type:
hora TYPE REF TO t.
That means hora will be a reference to a variable of TYPE t. Initially, this reference will be unbound, which is conceptually very similar to a null-reference in other programming languages. You can check that with:
IF ls_entity-hora IS BOUND.
...
IF ls_entity-hora IS NOT BOUND.
You can assign a time value with GET REFERENCE OF lwa_hora INTO ls_entity-hora. But now you have a reference to an existing variable. Change the value of lwa_hora, and the value of ls_entity-hora also changes. That might not always be what you want. So it might be better to create a new piece of data in memory for our reference to point to:
CREATE DATA ls_entity-hora.
Now ls_entity-hora is no longer unbound (or "null" if you want to call it that), it points to a new time-value of 000000. If you want to read or change the value of this nameless piece of data this reference points to, then you can do this with the dereferencing-operator ->*:
ls_entity-hora->* = lwa_hora.
If you intentionally want to set a reference to unbound (or "set the reference to null"), you can do that by clearing the reference:
CLEAR ls_entity-hora.
By the way: Representing a point in time by two separate variables of the types d and t fell out of fashion in the past decade. The current best practice for this situation is to use a single variable of type TIMESTAMP (if you need second precision) or TIMESTAMPL (if you need microsecond precision). A timestamp of 00000000000000 is obviously an illegal value, so it can be used to represent the absence of a point in time. This type also usually makes it much easier to communicate with a SAPUI5 frontend (like in your case), because many of the technologies for making oData services offer automatic conversion between Javascript Date and ABAP TIMESTAMP.
An alternative to heap allocating the time would be to store a boolean next to it, indicating whether it is set or not:
TYPES:
BEGIN OF optional_time,
time TYPE t,
is_null TYPE abap_bool,
END OF optional_time.
DATA(no_time) = VALUE optional_time( is_null = abap_true ).
" Setting to null:
DATA(some_time) = no_time.
" Setting to some time:
some_time = VALUE #( time = '12:30' ).
IF some_time = no_time.
" ...
ENDIF.
This sort of things is probably better to handle on front-end than on back-end.
SAP Gateway serializes ABAP Date/time initial values to NULL in the OData response if the corresponding property is nullable. You need to make sure this property is set to TRUE like in this sample
you can also set this property in runtime
TRY .
lo_action = model->get_entity_type( iv_entity_name = 'Z_REPORTType').
lo_property = lo_action->get_property( iv_property_name = 'Requested_Date').
lo_property->set_nullable( iv_nullable = abap_true ).
CATCH /iwbep/cx_mgw_busi_exception /iwbep/cx_mgw_med_exception /iwbep/cx_mgw_tech_exception INTO DATA(lo_exception).
ENDTRY.

Other ways to call/eval dynamic strings in Lua?

I am working with a third party device which has some implementation of Lua, and communicates in BACnet. The documentation is pretty janky, not providing any sort of help for any more advanced programming ideas. It's simply, "This is how you set variables...". So, I am trying to just figure it out, and hoping you all can help.
I need to set a long list of variables to certain values. I have a userdata 'ME', with a bunch of variables named MVXX (e.g. - MV21, MV98, MV56, etc).
(This is all kind of background for BACnet.) Variables in BACnet all have 17 'priorities', i.e., every BACnet variable is actually a sort of list of 17 values, with priority 16 being the default. So, typically, if I were to say ME.MV12 = 23, that would set MV12's priority-16 to the desired value of 23.
However, I need to set priority 17. I can do this in the provided Lua implementation, by saying ME.MV12_PV[17] = 23. I can set any of the priorities I want by indexing that PV. (Corollaries - what is PV? What is the underscore? How do I get to these objects? Or are they just interpreted from Lua to some function in C on the backend?)
All this being said, I need to make that variable name dynamic, so that i can set whichever value I need to set, based on some other code. I have made several attempts.
This tells me the object(MV12_PV[17]) does not exist:
x = 12
ME["MV" .. x .. "_PV[17]"] = 23
But this works fine, setting priority 16 to 23:
x = 12
ME["MV" .. x] = 23
I was trying to attempt some sort of what I think is called an evaluation, or eval. But, this just prints out function followed by some random 8 digit number:
x = 12
test = assert(loadstring("MV" .. x .. "_PV[17] = 23"))
print(test)
Any help? Apologies if I am unclear - tbh, I am so far behind the 8-ball I am pretty much grabbing at straws.
Underscores can be part of Lua identifiers (variable and function names). They are just part of the variable name (like letters are) and aren't a special Lua operator like [ and ] are.
In the expression ME.MV12_PV[17] we have ME being an object with a bunch of fields, ME.MV12_PV being an array stored in the "MV12_PV" field of that object and ME.MV12_PV[17] is the 17th slot in that array.
If you want to access fields dynamically, the thing to know is that accessing a field with dot notation in Lua is equivalent to using bracket notation and passing in the field name as a string:
-- The following are all equivalent:
x.foo
x["foo"]
local fieldname = "foo"
x[fieldname]
So in your case you might want to try doing something like this:
local n = 12
ME["MV"..n.."_PV"][17] = 23
BACnet "Commmandable" Objects (e.g. Binary Output, Analog Output, and o[tionally Binary Value, Analog Value and a handful of others) actually have 16 priorities (1-16). The "17th" you are referring to may be the "Relinquish Default", a value that is used if all 16 priorities are set to NULL or "Relinquished".
Perhaps your system will allow you to write to a BACnet Property called "Relinquish Default".

NSMassFormatter does not return localized values

I want to use iOS 8's new HealthKit NSFormatters to show the weight of a person according to locale. So 80 kgs in Europe should be formatted as 176.36 pounds in the US, but 80 kg in Europe.
For this I use the unitStringFromKilograms method, which according to the Docs should return:
A localized string representing the unit. This method selects the correct unit based on the formatter’s locale, the magnitude of the value, and the forPersonMassUse property.
However, the following piece of code, on several laptops with multiple locales and iOS devices with metric locales, always return 'pounds'.
Is this a bug or did I forget something so obvious that Apple didn't mention it in their docs?
import HealthKit
let massFormatter = NSMassFormatter()
massFormatter.forPersonMassUse = true // it doesn't matter if this is false
massFormatter.unitStyle = .Long
var massFormatterUnit = NSMassFormatterUnit.Kilogram
// This unitString SHOULD be according to locale, e.g. kg in Europe, pounds in us.
// instead it always returns 'pounds'
let unitString = massFormatter.unitStringFromKilograms(80, usedUnit: &massFormatterUnit)

How to implement GKTurnBasedMatchOutcomeCustomRange?

I've looked in the Apple GameKit Programming Guide, as well as the documentation of the GKTurnBasedParticipant to try and figure out how to implement the custom range. Apple docs say:
"Optionally, it may also use an OR operation to include a custom match outcome for your specific game. Game Center does not use the custom value; it exists to allow your game to provide additional information at the end of the match. The custom value must fit in the range provided by the GKTurnBasedMatchOutcomeCustomRange constant."
....
GKTurnBasedMatchOutcomeFourth = 9,
GKTurnBasedMatchOutcomeCustomRange = 0x00FF0000
};
typedef NSInteger GKTurnBasedMatchOutcome;*
I am not sure what to do to make a custom value or string for the outcome of the match. Any help would be appreciated!
Thanks,
Tams
I think you need to start from 1 rather than 0. Thus:
GKTurnBasedMatchOutcomeCustom0 = 1 | GKTurnBasedMatchOutcomeCustomRange
etc
Otherwise, the match is not considered to be over if you use GKTurnBasedMatchOutcomeCustom0.
You may want to check it out for yourself.
To create a custom match outcome enum, adapt the following to your purposes:
typedef enum
{
GKTurnBasedMatchOutcomeCustom0 = 0 | GKTurnBasedMatchOutcomeCustomRange,
GKTurnBasedMatchOutcomeCustom1 = 1 | GKTurnBasedMatchOutcomeCustomRange,
GKTurnBasedMatchOutcomeCustom2 = 2 | GKTurnBasedMatchOutcomeCustomRange,
...
GKTurnBasedMatchOutcomeCustomLast = 65536 | GKTurnBasedMatchOutcomeCustomRange
} GKTurnBasedMatchOutcome_Custom;
For example, GKTurnBasedMatchOutcomeCustom1 will be equal to 0xFF0000.
Essentially, you are allowed a maximum of 0xFFFF+1 (65536 in decimal) custom match outcome states.

How to declare an immutable graph with circular references?

I want to declare a graph of all states where the edges represent contiguous states. I think what I am trying to do might be called "tying the knot" (not sure about that though). It's not working like I expected, and I have a couple of questions.
First, I want a State type that has a string name and a list of contiguous states. But this declaration gives compiler error "...immediate cyclic reference...":
type State = string * (State list)
This way works:
type State(name:string, contigs: (State list)) =
let name = name
let contigs = contigs
But it's really not a requirement to name the members. A tuple is fine. How can I make that terse syntax work?
Second, the following code attempts to declare what should be three graphs of contiguous states (HI and AK are graphs consisting of a single node, all the remaining states constitute the last graph), followed by a list of all nodes. (For brevity I've only actually declared a handful of states here):
let rec hi = State("hi", [])
and mo = State("mo", [il ia])
and il = State("il", [mo])
and ia = State("ia", [mo])
and states = [hi,mo,il,ia]
This gives a variety of errors though including "mo will eventually be evaluated as part of it's own definition" and "expression was expected to have type 'a->'b but here has type State". I thought the 'rec' and 'and' keywords would allow this to work. Can I define this self referencing graph? If so, how?
The problem is your data structure and using invalid list element delimiters (should be semicolon). This works: (see edit)
type State =
| State of string * State list
let rec hi = State("hi", [])
and mo = State("mo", [il; ia])
and il = State("il", [mo])
and ia = State("ia", [mo])
let states = [hi; mo; il; ia]
Recursive references will be materialized as thunks (lazy). So you could, with a bit more typing do the same thing yourself with mutable lazys--just FYI--what you have is idiomatic.
EDIT
Intellisense didn't have a problem with it, but the compiler says
Recursive values cannot appear directly as a construction of the type 'List`1' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
You can fix this by using seq instead of list.
type State =
| State of string * State seq
let rec hi = State("hi", [])
and mo = State("mo", seq { yield il; yield ia })
and il = State("il", seq { yield mo })
and ia = State("ia", seq { yield mo })
let states = [hi; mo; il; ia]
Although what Daniel says is correct I would contest the assertion that it is "idiomatic" because that does not produce a very useful data structure for representing graphs in the general case. Specifically, it only permits the addition of new vertices and edges from them but not adding or removing edges between existing vertices. In particular, this basically means your graph must be statically defined as a constant in your source code so you cannot load such a graph from disk easily.
The idiomatic purely functional representation of a graph is to replace dereferences with dictionary lookups. For example, represent the graph as a Map from vertices to Sets of vertices to which there are edges:
> let g =
Map["hi", set[]; "mo", set["il"; "ia"]; "il", set["mo"]; "ia", set["mo"]];;
val g : Map<string,Set<string>> =
map
[("hi", set []); ("ia", set ["mo"]); ("il", set ["mo"]);
("mo", set ["ia"; "il"])]
For example, you can lookup the vertices directly reachable via edges from mo like this:
> g.["mo"];;
val it : Set<string> = set ["ia"; "il"]
This is easier to debug than the mutable representation but it has significant disadvantages:
Lookup in a purely functional dictionary like Map is at least 200× slower than dereferencing a pointer for traversing graphs (according to a quick test here).
The garbage collector no longer reclaims unreachable subgraphs for you. The imperative solution is to use a weak dictionary but there are no known purely functional weak dictionaries.
So this is only feasible if performance and leaks will not be a problem. This is most commonly the case when your graphs are small or static.

Resources