Swift 5 isEmoji method returns true for a number? - swift

Like in example below isEmoji method returns true for a number :
let scalars: [Unicode.Scalar] = ["🤓", "+", "1"]
for s in scalars {
print(s, "-->", s.properties.isEmoji)
}
// 🤓 --> true
// + --> false
// 1 --> true... wait what? 😦
But why and how to determine for the last case in my example.

I make a little search after facing this issue and found the answer in Apple's documentation. I am sharing with you so that you do not waste your valuable time in the future:
The final result is true because the ASCII digits have non-default
emoji presentations; some platforms render these with an alternate
appearance.
Because of this behavior, testing isEmoji alone on a
single scalar is insufficient to determine if a unit of text is
rendered as an emoji; a correct test requires inspecting multiple
scalars in a Character. In addition to checking whether the base
scalar has isEmoji == true, you must also check its default
presentation (see isEmojiPresentation) and determine whether it is
followed by a variation selector that would modify the presentation.
This property corresponds to the “Emoji” property in the Unicode
Standard.
SOLUTION
So you can check like the line below:
let scalars: [Unicode.Scalar] = ["🤓", "+", "1"]
for s in scalars {
print(s, "-->", (s.properties.isEmoji && s.properties.isEmojiPresentation))
}
// 🤓 --> true
// + --> false
// 1 --> false

Related

How can I make NodeJS's console.log always print output within a single line no matter what?

Is there any way to format the JSON logged through console.log in the terminal?
I'm logging a lot of debug data and if the the logged data exceeds a certain length, the terminal logs it prettified in many lines. I'd like to change it to log in one line, no matter the length of the data. Is there any way to do that?
In summary, I want to change this log style:
[12:34:56][DEBUG][CODE] - {
data: {
action: 'action',
url: '/path/to/my/api?variableOne=valueOne&variableTwo=valueTwo'
}
}
To this log style:
[12:34:56][DEBUG][CODE] - { data: { action: 'action', url: '/path/to/my/api?variableOne=valueOne&variableTwo=valueTwo' } }
Is there any way to format the JSON logged through console.log in the terminal?
Yes there is. Create a custom console object. See the docs for how to do that and what options you can specify. In particular, see also the inspectOptions docs.
The particular inspectOptions option you are looking for are breaklength and compact:
breakLength: <integer> The length at which input values are split across multiple lines. Set to Infinity to format the input as a single line (in combination with compact set to true or any number >= 1). Default: 80.
compact: <boolean> | <integer> Setting this to false causes each object key to be displayed on a new line. It will break on new lines in text that is longer than breakLength. If set to a number, the most n inner elements are united on a single line as long as all properties fit into breakLength. Short array elements are also grouped together. For more information, see the example below. Default: 3.
So since you asked
I'd like to change it to log in one line, no matter the length of the data
Then you probably want to do something like this:
const { Console } = require('node:console')
console = new Console({
stdout: process.stdout,
stderr: process.stderr,
// ignoreErrors, colorMode, groupIndentation
inspectOptions: {
// ...
breakLength: Infinity,
compact: true,
// ...
}
});
And then you can test it with console.log({a:1,b:2,c:3,hello:"world!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"});.
You can also just use the util.inspect function on specific objects you want to make a formatted string for, and then do console.log on the default global console object, passing the returned string.

How to parse new line in Scala grammar with flex/bison?

I want to parse Scala grammar with flex and bison. But I don't know how to parse the newline token in Scala grammar.
If I parse newline as a token T_NL, Here's the Toy.l for example:
...
[a-zA-Z_][a-zA-Z0-9_]* { yylval->literal = strdup(yy_text); return T_ID; }
\n { yylval->token = T_LN; return T_LN; }
[ \t\v\f\r] { /* skip whitespaces */ }
...
And here's the Toy.y for example:
function_def: 'def' T_ID '(' argument_list ')' return_expression '=' expression T_NL
;
argument_list: argument
| argument ',' argument_list
;
expression: ...
;
return_expression: ...
;
You could see that I have to skip T_NL in all other statements and definitions in Toy.y, which is really boring.
Please educate me with source code example!
This is a clear case where bison push-parsers are useful. The basic idea is that the decision to send an NL token (or tokens) can only be made when the following token has been identified (and, in one corner case, the second following token).
The advantage of push parsers is that they let us implement strategies like this, where there is not necessarily a one-to-one relationship between input lexemes and tokens sent to the parser. I'm not going to deal with all the particularities of setting up a push parser (though it's not difficult); you should refer to the bison manual for details. [Note 1]
First, it's important to read the Scala language description with care. Newline processing is described in section 2.13:
A newline in a Scala source text is treated as the special token “nl” if the three following criteria are satisfied:
The token immediately preceding the newline can terminate a statement.
The token immediately following the newline can begin a statement.
The token appears in a region where newlines are enabled.
Rules 1 and 2 are simple lookup tables, which are precisely defined in the following two paragraphs. There is just one minor exception to rule 2 has a minor exception, described below:
A case token can begin a statement only if followed by a class or object token.
One hackish possibility to deal with that exception would be to add case[[:space:]]+class and case[[:space:]]+object as lexemes, on the assumption that no-one will put a comment between case and class. (Or you could use a more sophisticated pattern, which allows comments as well as whitespace.) If one of these lexemes is recognised, it could either be sent to the parser as a single (fused) token, or it could be sent as two tokens using two invocations of SEND in the lexer action. (Personally, I'd go with the fused token, since once the pair of tokens has been recognised, there is no advantage to splitting them up; afaik, there's no valid program in which case class can be parsed as anything other than case class. But I could be wrong.)
To apply rules one and two, then, we need two lookup tables indexed by token number: token_can_end_stmt and token_cannot_start_stmt. (The second one has its meaning reversed because most tokens can start statements; doing it this way simplifies initialisation.)
/* YYNTOKENS is defined by bison if you specify %token-tables */
static bool token_can_end_stmt[YYNTOKENS] = {
[T_THIS] = true, [T_NULL] = true, /* ... */
};
static bool token_cannot_start_stmt[YYNTOKENS] = {
[T_CATCH] = true, [T_ELSE] = true, /* ... */
};
We're going to need a little bit of persistent state, but fortunately when we're using a push parser, the scanner does not need to return to its caller every time it recognises a token, so we can keep the persistent state as local variables in the scan loop. (That's another advantage of the push-parser architecture.)
From the above description, we can see that what we're going to need to maintain in the scanner state are:
some indication that a newline has been encountered. This needs to be a count, not a boolean, because we might need to send two newlines:
if two tokens are separated by at least one completely blank line (i.e a line which contains no printable characters), then two nl tokens are inserted.
A simple way to handle this is to simply compare the current line number with the line number at the previous token. If they are the same, then there was no newline. If they differ by only one, then there was no blank line. If they differ by more than one, then there was either a blank line or a comment (or both). (It seems odd to me that a comment would not trigger the blank line rule, so I'm assuming that it does. But I could be wrong, which would require some adjustment to this scanner.) [Note 2]
the previous token (for rule 1). It's only necessary to record the token number, which is a simple small integer.
some way of telling whether we're in a "region where newlines are enabled" (for rule 3). I'm pretty sure that this will require assistance from the parser, so I've written it that way here.
By centralising the decision about sending a newline into a single function, we can avoid a lot of code duplication. My typical push-parser architecture uses a SEND macro anyway, to deal with the boilerplate of saving the semantic value, calling the parser, and checking for errors; it's easy to add the newline logic there:
// yylloc handling mostly omitted for simplicity
#define SEND_VALUE(token, tag, value) do { \
yylval.tag = value; \
SEND(token); \
} while(0);
#define SEND(token) do { \
int status = YYPUSH_MORE; \
if (yylineno != prev_lineno) \
&& token_can_end_stmt[prev_token] \
&& !token_cannot_start_stmt[token] \
&& in_new_line_region) { \
status = yypush_parse(ps, T_NL, NULL, &yylloc, &nl_enabled); \
if (status == YYPUSH_MORE \
&& yylineno - prev_lineno > 1) \
status = yypush_parse(ps, T_NL, NULL, &yylloc, &nl_enabled); \
} \
nl_encountered = 0; \
if (status == YYPUSH_MORE) \
status = yypush_parse(ps, token, &yylval, &yylloc, &nl_enabled); \
if (status != YYPUSH_MORE) return status; \
prev_token = token; \
prev_lineno = yylineno; \
while (0);
Specifying the local state in the scanner is extremely simple; just place the declarations and initialisations at the top of your scanner rules, indented. Any indented code prior to the first rule is inserted directly into yylex, almost at the top of the function (so it is executed once per call, not once per lexeme):
%%
int nl_encountered = 0;
int prev_token = 0;
int prev_lineno = 1;
bool nl_enabled = true;
YYSTYPE yylval;
YYLTYPE yylloc = {0};
Now, the individual rules are pretty simple (except for case). For example, we might have rules like:
"while" { SEND(T_WHILE); }
[[:lower:]][[:alnum:]_]* { SEND_VALUE(T_VARID, str, strdup(yytext)); }
That still leaves the question of how to determine if we are in a region where newlines are enabled.
Most of the rules could be handled in the lexer by just keeping a stack of different kinds of open parentheses, and checking the top of the stack: If the parenthesis on the top of the stack is a {, then newlines are enabled; otherwise, they are not. So we could use rules like:
[{([] { paren_stack_push(yytext[0]); SEND(yytext[0]); }
[])}] { paren_stack_pop(); SEND(yytext[0]); }
However, that doesn't deal with the requirement that newlines be disabled between a case and its corresponding =>. I don't think it's possible to handle that as another type of parenthesis, because there are lots of uses of => which do not correspond with a case and I believe some of them can come between a case and it's corresponding =>.
So a better approach would be to put this logic into the parser, using lexical feedback to communicate the state of the newline-region stack, which is what is assumed in the calls to yypush_parse above. Specifically, they share one boolean variable between the scanner and the parser (by passing a pointer to the parser). [Note 3] The parser then maintains the value of this variable in MRAs in each rule which matches a region of potentially different newlinedness, using the parse stack itself as a stack. Here's a small excerpt of a (theoretical) parser:
%define api.pure full
%define api.push-pull push
%locations
%parse-param { bool* nl_enabled; }
/* More prologue */
%%
// ...
/* Some example productions which modify nl_enabled: */
/* The actions always need to be before the token, because they need to take
* effect before the next lookahead token is requested.
* Note how the first MRA's semantic value is used to keep the old value
* of the variable, so that it can be restored in the second MRA.
*/
TypeArgs : <boolean>{ $$ = *nl_enabled; *nl_enabled = false; }
'[' Types
{ *nl_enabled = $1; } ']'
CaseClause : <boolean>{ $$ = *nl_enabled; *nl_enabled = false; }
"case" Pattern opt_Guard
{ *nl_enabled = $1; } "=>" Block
FunDef : FunSig opt_nl
<boolean>{ $$ = *nl_enabled; *nl_enabled = true; }
'{' Block
{ *nl_enabled = $3; } '}'
Notes:
Push parsers have many other advantages; IMHO they are they are the solution of choice. In particular, using push parsers avoids the circular header dependency which plagues attempts to build pure parser/scanner combinations.
There is still the question of multiline comments with preceding and trailing text:
return /* Is this comment
a newline? */ 42
I'm not going to try to answer that question.)
It would be possible to keep this flag in the YYLTYPE structure, since only one instance of yylloc is ever used in this example. That might be a reasonable optimisation, since it cuts down on the number of parameters sent to yypush_parse. But it seemed a bit fragile, so I opted for a more general solution here.

How to use Optional in Netlogo Extensions

I want to create a netlogo primitive that may receive a boolean or may not. Therefore I want make possible to the user that he uses the primitive of these two ways:
1:
ask Walkers [
qlearningextension:learning
]
2:
ask Walkers [
qlearningextension:learning true
]
I tried to do that with OptionalType, but I could not make it. Is it possible to do what I want? If so, how can I do it?
So OptionalType unfortunately only works with CommandBlockType. For a good example of how that works, check out the sample-scala extension (maybe that's where you saw a reference to it in the first pace). OptionalType will not work with BooleanType.
There is a secondary option, that's a little hacky. You can use RepeatableType along with setting defaultOption and minimumOption in your syntax (so NetLogo knows that 0 arguments is okay/expected). Scala code example:
object RepeatableTypeTest extends api.Command {
override def getSyntax =
commandSyntax(
right = List(BooleanType | RepeatableType),
defaultOption = Some(0),
minimumOption = Some(0)
)
def perform(args: Array[api.Argument], context: api.Context) {
println(args.length)
if (args.length > 0) {
val ref = args(0).getBoolean
println(ref)
} else {
println("No argument given!")
}
}
}
Then you just have to wrap calls with the boolean argument in parenthesis, so NetLogo knows you're not starting a new command (it expects the defaultOption without the parens):
to test
sample-scala:rep-bool
(sample-scala:rep-bool true)
(sample-scala:rep-bool false)
(sample-scala:rep-bool false true false true false)
end
The problem with this, as you can see in the example, is if your users want to they can provide extra useless booleans: (sample-scala:rep-bool false true false false true false false). If your code ignores them they won't have an effect, but they could be confusing or weird to extension users.

Where does a variable in a match arm in a loop come from?

I am trying to implement an HTTP client in Rust using this as a starting point. I was sent to this link by the rust-lang.org site via one of their rust-by-example suggestions in their TcpStream page. I'm figuring out how to read from a TcpStream. I'm trying to follow this code:
fn handle_client(mut stream: TcpStream) {
// read 20 bytes at a time from stream echoing back to stream
loop {
let mut read = [0; 1028];
match stream.read(&mut read) {
Ok(n) => {
if n == 0 {
// connection was closed
break;
}
stream.write(&read[0..n]).unwrap();
}
Err(err) => {
panic!(err);
}
}
}
}
Where does the n variable come from? What exactly is it? The author says it reads 20 bytes at a time; where is this coming from?
I haven't really tried anything yet because I want to understand before I do.
I strongly encourage you to read the documentation for the tools you use. In this case, The match Control Flow Operator from The Rust Programming Language explains what you need to know.
From the Patterns that Bind to Values section:
In the match expression for this code, we add a variable called state to the pattern that matches values of the variant Coin::Quarter. When a Coin::Quarter matches, the state variable will bind to the value of that quarter’s state. Then we can use state in the code for that arm, like so:
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => {
println!("State quarter from {:?}!", state);
25
},
}
}
If we were to call value_in_cents(Coin::Quarter(UsState::Alaska)), coin would be Coin::Quarter(UsState::Alaska). When we compare that value with each of the match arms, none of them match until we reach Coin::Quarter(state). At that point, the binding for state will be the value UsState::Alaska. We can then use that binding in the println! expression, thus getting the inner state value out of the Coin enum variant for Quarter.
There is an entire chapter about the pattern matching syntax available and where it can be used.
Figured it out, this is what's happening:
match stream.read(&mut read) {
This line is telling the software to pass stream.read(&mut read) to Ok(n) because stream.read returns the number of bytes read. I'm still not sure why they specify 20 bytes at a time as being read.

Fastlane set options auto value

I would like to submit my lane with optional options. So for example the lane:
lane :mylane do |options|
mailgun(
to: "#{options[:mailto]}"
....
)
end
How do I give :mailto a default value? So if I would run fastlane mylane it would automatically set :mailto to mail#example.com.
But if I would runfastlane mylane mailto:"secondmail#example.com" it would use that value
As Lyndsey Ferguson pointed out in a comment on this answer, the following is simplest:
mail_addr = options.fetch(:mailto, 'mail#example.com')
where the first parameter of fetch is the option to fetch, and the second is the default value if the option was not passed in.
I just want to add that this works a lot better than the other suggestion:
options[:mailto] || 'mail#example.com'
when dealing with boolean options.
Fastlane (or maybe Ruby) interprets true, false, yes, and no as boolean values instead of strings (maybe others too, though I tried N, n, NO, and FALSE and they were treated as strings), so if in your lane implementation you had:
options[:my_option] || true
or
(options[:my_option] || 'true') == 'true'
you would get unexpected behaviour.
If you didn't pass in myOption at all, this would default to true as you would expect. If you passed in true this would also return true. But if you passed in false this would turn into true, which you of course wouldn't want.
Using options.fetch(:myOption, true) works great with boolean flags like the ones mentioned above and therefore seems better to use in general.
Here's a very thorough example in case you want to test it yourself:
lane :my_lane do |options|
puts("You passed in #{options[:my_option]}")
my_option = options[:my_option] || true
if my_option
puts('Using options[:my_option], the result is true')
else
puts('Using options[:my_option] the result is false')
end
my_option_fetched = options.fetch(:my_option, true)
if my_option_fetched
puts('Using fetched, the result is true')
else
puts('Using fetched, the result is false')
end
end
Outputs:
fastlane my_lane my_option:true
You passed in true
Using options[:my_option], the result is true
Using fetched, the result is true
fastlane my_lane my_option:false
You passed in false
Using options[:my_option], the result is true
Using fetched, the result is false
fastlane my_lane my_option:no
You passed in false
Using options[:my_option], the result is true
Using fetched, the result is false
Note, e.g. FALSE would default to true as it is not being interpreted as a boolean, which seems reasonable to me.
(Fastlane 1.77.0, Ruby 2.7.2)
EDIT: It's worth noting that if you pass an empty string instead of nothing/null you would not get the default value from the fetch method.
I'm not sure there's a way to make Fastlane pass a default. The processing is pretty simple:
https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/command_line_handler.rb#L10
But you can easily do this in your Fastfile:
lane :mylane do |options|
mail_addr = options[:mailto] || "mail#example.com"
mailgun(
to: "#{mail_addr}"
....
)
end