Is this response from the compiler valid? - swift

The following code invokes an error. I could not find any information on this is in the reference. The lack of whitespace on the right hand side of the '=' operator is an error.
let names =["Anna", "Alex", "Brian", "Jack"]
Any other combination of this syntax compiles. Anyone know if this is truly invalid syntax per what we know of Swift right now?
EDIT: Error response is: Prefix/postfix '=' is reserved
ANSWER: This excerpt seems to answer my question. I just couldn't find it for the longest time:
The whitespace around an operator is used to determine whether an
operator is used as a prefix operator, a postfix operator, or a binary
operator. This behavior is summarized in the following rules:
If an operator has whitespace around both sides or around neither
side, it is treated as a binary operator. As an example, the +
operator in a+b and a + b is treated as a binary operator. If an
operator has whitespace on the left side only, it is treated as a
prefix unary operator. As an example, the ++ operator in a ++b is
treated as a prefix unary operator. If an operator has whitespace on
the right side only, it is treated as a postfix unary operator. As an
example, the ++ operator in a++ b is treated as a postfix unary
operator. If an operator has no whitespace on the left but is followed
immediately by a dot (.), it is treated as a postfix unary operator.
As an example, the ++ operator in a++.b is treated as a postfix unary
operator (a++ . b rather than a ++ .b).
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/us/jEUH0.l

Add a space after the =. (=[ looks too sad to be an operator.) It's probably seeing =value as a use of a (possible, but not implemented) prefix operator.
Swift isn't entirely whitespace-agnostic like C... in particular, it uses whitespace to distinguish prefix from postfix operators (because ++i++ in C is a grammar oddity). But it's not ridiculously strict about whitespace like Python either.

Try adding a space between the = and [.
When the equals sign is directly in front of the bracket, the compiler assumes that you are trying to perfom a prefix operation on the array.

Place a space between = and [,
let names = ["Anna", "Alex", "Brian", "Jack"]
It seems that =[ is a reserved operator.

Related

Oddities in fail2ban regex

This appears to be a bug in fail2ban, with different behaviour between the fail2ban-regex tool and a failregex filter
I am attempting to develop a new regex rule for fail2ban, to match:
\"%20and%20\"x\"%3D\"x
When using fail2ban-regex, this appears to produce the desired result:
^<HOST>.*GET.*\\"%20and%20\\"x\\"%3D\\"x.* 200.*$
As does this:
^<HOST>.*GET.*\\\"%20and%20\\\"x\\\"%3D\\\"x.* 200.*$
However, when I put either of these into a filter, I get the following error:
Failed during configuration: '%' must be followed by '%' or '(', found:…
To have this work in a filter you have to double-up the ‘%’, ie ‘%%’:
^<HOST>.*GET.*\\\"%%20and%%20\\\"x\\\"%%3D\\\"x.* 200.*$
While this gets the required hits running as a filter, it gets none running through fail2ban-regex.
I tried the \\\\ as Andre suggested below, but this gets no results in fail2ban-regex.
So, as this appears to be differential behaviour, I am going to file it as a bug.
According to Python's own site a singe backslash "\" has to be written as "\\\\" and there's no mention of %.
Regular expressions use the backslash character ('') to indicate
special forms or to allow special characters to be used without
invoking their special meaning. This collides with Python’s usage of
the same character for the same purpose in string literals; for
example, to match a literal backslash, one might have to write '\\'
as the pattern string, because the regular expression must be \, and
each backslash must be expressed as \ inside a regular Python string
literal
I would just go with:
failregex = (?i)^<HOST> -.*"(GET|POST|HEAD|PUT).*20and.*3d.*$
the .* wil match anything inbetween anyways and (?i) makes the entire regex case-insensitive

Not able to understand a command in perl

I need help to understand what below command is doing exactly
$abc{hier} =~ s#/tools.*/dfII/?.*##g;
and $abc{hier} contains a path "/home/test1/test2/test3"
Can someone please let me know what the above command is doing exactly. Thanks
s/PATTERN/REPLACEMENT/ is Perl's substitution operator. It searches a string for text that matches the regex PATTERN and replaces it with REPLACEMENT.
By default, the substitution operator works on $_. To tell it to work on a different variable, you use the binding operator - =~.
The default delimiter used by the substitution operator is a slash (/) but you can change that to any other character. This is useful if your PATTERN or your REPLACEMENT contains a slash. In this case, the programmer has used # as the delimiter.
To recap:
$abc{hier} =~ s#PATTERN#REPLACEMENT#;
means "look for text in $abc{hier} that matches PATTERN and replace it with REPLACEMENT.
The substitution operator also has various options that change its behaviour. They are added by putting letters after the final delimiter. In this case we have a g. That means "make the substitution global" - or match and change all occurrences of PATTERN.
In your case, the REPLACEMENT string is empty (we have two # characters next to each other). So we're replacing the PATTERN with nothing - effectively deleting whatever matches PATTERN.
So now we have:
$abc{hier} =~ s#PATTERN*##g;
And we know it means, "in the variable $abc{hier}, look for any string that matches PATTERN and replace it with nothing".
The last thing to look at is the PATTERN (or regular expression - "regex"). You can get the full definition of regexes in perldoc perlre. But to explain what we're using here:
/tools : is the fixed string "/tools"
.* : is zero or more of any character
/dfII : is the fixed string "/dfII"
/? : is an optional slash character
.* : is (again) zero or more of any character
So, basically, we're removing bits of a file path from a value that's stored in a hash.
This =~ means "Do a regex operation on that variable."
(Actually, as ikegami correctly reminds me, it is not necessarily only regex operations, because it could also be a transliteration.)
The operation in question is s#something#else#, which means replace the "something" with something "else".
The g at the end means "Do it for all occurences of something."
Since the "else" is empty, the replacement has the effect of deleting.
The "something" is a definition according to regex syntax, roughly it means "Starting with '/tools' and later containing '/dfII', followed pretty much by anything until the end."
Note, the regex mentions at the end /?.*. In detail, this would mean "A slash (/) , or maybe not (?), and then absolutely anything (.) any number of times including 0 times (*). Strictly speaking it is not necessary to define "slash or not", if it is followed by "anything any often", because "anything" includes as slash, and anyoften would include 0 or one time; whether it is followed by more "anything" or not. I.e. the /? could be omitted, without changing the behaviour.
(Thanks ikeagami for confirming.)
$abc{hier} =~ s#/tools.*/dfII/?.*##g;
The above commands use regular expression to strip/remove trailing /tools.*/dfII and
/tools.*/dfII/.* from value of hier member of %abc hash.
It is pretty basic perl except non standard regular expression limiters (# instead of standard /). It allows to avoid escaping / inside the regular expression (s/\/tools.*\/dfII\/?.*//g).
My personal preferred style-guide would make it s{/tools.*/dfII/?.*}{}g .

Why are leading-hyphen options permitted on `use` lines without fat comma and with strict?

Why is the following use line legal Perl syntax? (Adapted from the POD for parent; tested on Perl 5.26.2 x64 on Cygwin.)
package MyHash;
use strict;
use Tie::Hash;
use parent -norequire, "Tie::StdHash";
# ^^^^^^^^^^ A bareword with nothing to protect it!
Under -MO=Deparse, the use line becomes
use parent ('-norequire', 'Tie::StdHash');
but I can't tell from the use docs where the quoting on -norequire comes from.
If use strict were not in force, I would understand it. The bareword norequire would become the string "norequire", the unary minus would turn that string into "-bareword", and the resulting string would go into the use import list. For example:
package MyHash;
use Tie::Hash;
use parent -norequire, "Tie::StdHash";
Similarly, if there were a fat comma, I would understand it. -foo => bar becomes "-foo", bar because => turns foo into "foo", and then the unary minus works its magic again. For example:
package MyHash;
use strict;
use Tie::Hash;
use parent -norequire => "Tie::StdHash";
Both of those examples produce the same deparse for the use line. However, both have quoting that the original example does not. What am I missing that makes the original example (with strict, without =>) legal? Thanks!
You already cited perldoc perlop, but it is relevant here.
Unary - performs arithmetic negation if the operand is numeric, including any string that looks like a number. If the operand is an identifier, a string consisting of a minus sign concatenated with the identifier is returned. ... One effect of these rules is that -bareword is equivalent to the string "-bareword".
This behavior of the unary minus operator is applied to the bareword before the strict checks are applied. Therefore, unary minus is a kind of quoting operator that also works in strict mode.
Similarly, barewords as the invocant in method invocation do not need to be quoted as long as they are not a function call:
Foo->bar; # 'Foo'->bar(); --- but only if no sub Foo exists
print->bar; # print($_)->bar();
However, the unary minus behaviour seems to be due to constant folding, not due to a special case in the parser. For example, this code
use strict;
0 ? foo : bar;
will only complain about the bareword "bar" being disallowed, suggesting that the bareword check happens very late during parsing and compilation. In the unary minus case, the bareword will already have been constant-folded into a proper string value at that point, and no bareword remains visible.
While this is arguably buggy, it is also impossible to change without breaking backwards compatibility – and this behaviour is used by many modules such as use parent to communicate options. Compare also similar idioms on command line interfaces, where options usually begin with a dash.
From perlop
Symbolic Unary Operators
Unary "-" performs arithmetic negation if the operand is numeric, including any
string that looks like a number. If the operand is an identifier, a string
consisting of a minus sign concatenated with the identifier is returned.
Otherwise, if the string starts with a plus or minus, a string starting with
the opposite sign is returned. One effect of these rules is that -bareword is
equivalent to the string "-bareword". If, however, the string begins with a
non-alphabetic character (excluding "+" or "-"), Perl will attempt to convert
the string to a numeric and the arithmetic negation is performed. If the string
cannot be cleanly converted to a numeric, Perl will give the warning Argument
"the string" isn't numeric in negation (-) at ....
So because of the rules of Perl parsing -name is treated as "-name" even under use strict

Simple Int sum error

I am just starting out with Swift, coming from Objective-C. I have this line:
self.collectionView?.insertItems(at: [IndexPath.init(row: (self.flights.count -1), section: 0)])
I get an error saying: Expected ',' separator after 'count'.
Why on earth can I not do a simple sum, the count -1? A little quirk of Swift I haven't yet learnt, or its too early in the morning...
Referring to Apple's "Lexical Structure" Documentation:
The whitespace around an operator is used to determine whether an
operator is used as a prefix operator, a postfix operator, or a binary
operator. This behavior is summarized in the following rules:
If an operator has whitespace around both sides or around neither side, it is treated as a binary operator. As an example, the +++
operator in a+++b and a +++ b is treated as a binary operator.
If an operator has whitespace on the left side only, it is treated as a prefix unary operator. As an example, the +++ operator in a +++b
is treated as a prefix unary operator.
If an operator has whitespace on the right side only, it is treated as a postfix unary operator. As an example, the +++ operator in a+++ b
is treated as a postfix unary operator.
If an operator has no whitespace on the left but is followed immediately by a dot (.), it is treated as a postfix unary operator.
As an example, the +++ operator in a+++.b is treated as a postfix
unary operator (a+++ .b rather than a +++ .b).
Note: ++ and -- has been removed from Swift 3. For more information, check 0004 Swift evolution proposal.
Means that the minus operator in self.flights.count -1 treated as prefix unary operator (second rule).
To make it more clear, the compiler reads self.flights.count -1 as: self.flights.count, next to it there is a minus one, but NOT a subtraction operation. By applying the second rule, the minus is a prefix unary operator for the 1.
Obviously, you want the compiler to treat the minus operator as a binary operator, so what you should do is to add whitespace around both sides of the minus (applying the first rule):
self.collectionView.insertItems(at: [IndexPath.init(row: (flights.count - 1), section: 0)])
Hope this helped.
All you need to do is add a space
self.collectionView?.insertItems(at: [IndexPath.init(row: (self.flights.count - 1), section: 0)])

Funky 'x' usage in perl

My usual 'x' usage was :
print("#" x 78, "\n");
Which concatenates 78 times the string "#". But recently I came across this code:
while (<>) { print if m{^a}x }
Which prints every line of input starting with an 'a'. I understand the regexp matching part (m{^a}), but I really don't see what that 'x' is doing here.
Any explanation would be appreciated.
It's a modifier for the regex. The x modifier tells perl to ignore whitespace and comments inside the regex.
In your example code it does not make a difference because there are no whitespace or comments in the regex.
The "x" in your first case, is a repetition operator, which takes the string as the left argument and the number of times to repeat as the right argument. Perl6 can replicate lists using the "xx" repetition operator.
Your second example uses the regular expression m{^a}x. While you may use many different types of delimiters, neophytes may like to use the familiar notation, which uses a forward slash: m/^a/x
The "x" in a regex is called a modifier or a flag and is but one of many optional flags that may be used. It is used to ignore whitespace in the regex pattern, but it also allows the use of normal comments inside. Because regex patterns can get really long and confusing, using whitespace and comments are very helpful.
Your example is very short (all it says is if the first letter of the line starts with "a"), so you probably wouldn't need whitespace or comments, but you could if you wanted to.
Example:
m/^a # first letter is an 'a'
# <-- you can put more regex on this line because whitespace is ignored
# <-- and more here if you want
/x
In this use case 'x' is a regex modifier which "Extends your pattern's legibility by permitting whitespace and comments." according to the perl documentation. However it seems redundant here