I have much of validation like this
if (someBoolean) return
Can I create an infix operator with following syntax?
returnif someBoolean
No, you can't write this operator (which would be prefix rather than infix), for two reasons:
operators can't be defined with alphanumeric characters (see the docs for a rundown of what they can be defined with)
you can't write a function (which is what custom operators are) that results in a return in it's calling scope i.e. return within the operator function would just return from the operator function, not from the function you used the operator in
Related
I have read Kotlin docs as well as the wikipedia links (https://en.wikipedia.org/wiki/Infix_notation#:~:text=Infix%20notation%20is%20the%20notation,plus%20sign%20in%202%20%2B%202), but unfortunately I am still unable to make use of this notation in my code.
Could someone please let me know, how can I use it?
Before jumping on to the code, let’s look at the rules of it’s usage (From the docs: https://kotlinlang.org/docs/functions.html#infix-notation):
Infix notation must be used with member functions or extension functions
They must have a single parameter
The parameter must not accept variable number of arguments and must have no default value.
Keeping these pointers in mind, you can achieve the following:
fun Int.add(x: Int) = this.plus(x) //This is a simple Extension function without infix notation
infix fun Int.subtract(x: Int) = this.minus(x) //Added infix notation here
fun main() {
val sum = 10.add(20)
println(sum) //prints 30
val sub = 100 subtract 30 //Notice that there is no dot(.) and parenthesis
println(sub) //prints 70
}
This is how we can use infix notations and get rid of the dots(.) and parenthesis and they will work the same.
This increases code readability.
I want to use $1 in adart regular expression to get the grouping in the expression.
Just like javascript regular expressions.
void main() {
// javascript
// 'hello-world'.replace(/-(w)/, '+$1'); // hello+world
print('hello-world'.replaceAll(RegExp(r'-(w)'), '+\$1')); // hello+$1orld
}
Completely unexpected.
Expected result hello+world, actual resulthello+$1orld
The Dart replaceAll method does not treat its second argument as a replacement pattern.
Rather than introduce a new language for specifying replacements in a string, Dart allows you to use a normal Dart expression to compute the replacement.
Dart has a short syntax for functions, so this is not much longer than the string, but it allows you to insert arbitrarily complicated computations when necessary.
So, use the replaceAllMapped function and write the replacement as follows:
print('hello-world'.replaceAllMapped(RegExp(r'-(w)'), (m) => '+${m[1]}'));
For this particular example, the RegExp is so simple that you can replace with a plain string:
print('hello-world'.replaceAll(RegExp(r'-(?=w)'), '+'));
This replaces a - with a + only when the - is followed by a w.
Say I have a scope like this:
scope :by_templates, ->(t) { joins(:template).where('templates.label ~* ?', t) }
How can I retrieve multiple templates with t like so?
Document.first.by_templates(%w[email facebook])
This code returns this error.
PG::DatatypeMismatch: ERROR: argument of AND must be type boolean, not type record
LINE 1: ...template_id" WHERE "documents"."user_id" = $1 AND (templates...
PostgreSQL allows you to apply a boolean valued operator to an entire array of values using the op any(array_expr) construct:
9.23.3. ANY/SOME (array)
expression operator ANY (array expression)
expression operator SOME (array expression)
The right-hand side is a parenthesized expression, which must yield an array value. The left-hand expression is evaluated and compared to each element of the array using the given operator, which must yield a Boolean result. The result of ANY is “true” if any true result is obtained. The result is “false” if no true result is found (including the case where the array has zero elements).
PostgreSQL also supports the array constructor syntax for creating arrays:
array[value, value, ...]
Conveniently, ActiveRecord will expand a placeholder as a comma-delimited list when the value is an array.
Putting these together gives us:
scope :by_templates, ->(templates) { joins(:template).where('templates.label ~* any(array[?])', templates) }
As an aside, if you're using the case-insensitive regex operator (~*) as a case-insensitive comparison (i.e. no real regex pattern matching going on) then you might want to use upper instead:
# Yes, this class method is still a scope.
def self.by_templates(templates)
joins(:template).where('upper(templates.label) = any(array[?])', templates.map(&:upcase) }
end
Then you could add an index to templates on upper(label) to speed things up and avoid possible issues with stray regex metacharacters in the templates. I tend to use upper case for this sort of thing because of oddities lie 'ß'.upcase being 'SS' but 'SS'.downcase being 'ss'.
I don't know how to calculate my function.
I am trying to assign my output expression to a function, but I can't calculate it in my function with parameters. It always returns an expression.
The ":=" operator quotes (does not evaluate) its arguments. Note that as you defined it, the body of the function is %o6 instead of its value.
There are a couple of ways to achieve what you want. Try this: use the quote-quote '' operator to paste the expression into the function definition like this.
ge(r, t) := ''%o6;
Let's say that for some strange reason I want to have this function:
let (~-) (str:string) = 42
So I can do something like this and get 42 as result:
-"test"
val it : int = 42
Which is fine. But now when I do:
let a = 100
-a
I get:
error FS0001: This expression was expected to have type
string
but here has type
int
Any idea why is this happening?
When you define operators using let, the new definition hides all previous definition of the operator. So in your example, you are hiding the default implementation of the unary minus (which works for numbers) and replacing it with a new operator that only works on strings.
It is not easy to re-define overloaded operators on built-in types. If you need that, it is probably better idea to avoid using operators (just use a function). However, if you want to provide an overloaded operator for a custom type, you can do this by adding operator as a static member:
type MinusString(s:string) =
member x.Value = s
/// Provide unary minus for MinusString values
static member (~-) (ms:MinusString) =
MinusString("-" + ms.Value)
-(MinusString "hi") // Returns "-hi"
If you really want to redefine built-in operator like unary minus and make it work on string, then there is actually a way to do this using a trick described in earlier SO answers. However, I would only use this if you have a good reason.
Simply, you overwrote the minus operator with one that takes a string and returns an int, then tried to apply it to an int, which it can't do anymore.