How to validate each item in Observable and return an error if condition failed?
Now I'm using switchMap with if inside, but this solution looks not very nice:
Observable.just(1, 2, 3, -1, 4)
.switchMap(x -> {
if (x >= 0) {
return Observable.just(x);
} else {
return Observable.error(new Exception("Input value should be positive"));
}
})
.subscribe(
x -> System.out.printf("value=%d\n", x),
err -> System.out.printf("error: %s\n", err.getMessage())
);
Can I use any built-in method instead of this?
You can use doOnNext() to throw your exception.
Observable.just(1, 2, 3, -1, 4)
.doOnNext(x -> {
if (x < 0) throw Exception("Input value should be positive");
})
.subscribe(
x -> System.out.printf("value=%d\n", x),
err -> System.out.printf("error: %s\n", err.message)
);
Related
I have a problem with adding new opcode to solidity. I'm using solc (on C++) and geth(ethereum on Go). I want to add new opcode, that takes address payable, uint256, uint256, bytes memory and returns bytes memory. So I have a problem with return value.
Some peaces of code below, I will skip some files, to make question shorter.
Solc
libsolidity/codegen/ExpressionCompiler.cpp
// ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::MyOpcode:
{
acceptAndConvert(*arguments[0], *function.parameterTypes()[0], true);
acceptAndConvert(*arguments[1], *function.parameterTypes()[1], true);
acceptAndConvert(*arguments[2], *function.parameterTypes()[2], true);
arguments[3]->accept(*this);
utils().fetchFreeMemoryPointer();
utils().packedEncode(
{arguments[3]->annotation().type},
{TypeProvider::array(DataLocation::Memory, true)}
);
utils().toSizeAfterFreeMemoryPointer();
m_context << Instruction::MYOPCODE;
}
libsolidity/analysis/GlobalContext.cpp
// inline vector<shared_ptr<MagicVariableDeclaration const>> constructMagicVariables()
magicVarDecl("myopcode", TypeProvider::function(strings{"address payable", "uint256", "uint256", "bytes memory"}, strings{"bytes memory"}, FunctionType::Kind::MyOpcode, false, StateMutability::Payable)),
libevmasm/Instruction.cpp
// static std::map<Instruction, InstructionInfo> const c_instructionInfo =
{ Instruction::MYOPCODE, { "MYOPCODE", 0, 5, 1, true, Tier::Base } }
Geth
core/vm/jump_table.go
// func newFrontierInstructionSet() JumpTable {
CALLACTOR: {
execute: opMyOpCode,
dynamicGas: gasCallActor,
minStack: minStack(5, 1),
maxStack: maxStack(5, 1),
memorySize: memoryReturn,
writes: true,
returns: true,
},
core/vm/instructions.go
func opMyOpcode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
inoffset, insize := callContext.stack.pop(), callContext.stack.pop()
params := callContext.memory.GetPtr(int64(inoffset.Uint64()), int64(insize.Uint64()))
secondValue := callContext.stack.pop()
firstValue := callContext.stack.pop()
addr := callContext.stack.pop()
// ... Do smth with input ...
outoffset := inoffset.Uint64() + insize.Uint64()
callContext.memory.Set(outoffset, 1, []byte{0x2})
tmp := make([]byte, 1)
tmp[0] = 0x98
callContext.memory.Set(outoffset + 1, 1, tmp)
callContext.stack.push(uint256.NewInt().SetUint64(outoffset))
return tmp, nil
}
Smart contract
pragma solidity >=0.6.0; // SPDX-License-Identifier: GPL-3
contract test {
event ReturnValue(address payable _from, bytes data);
function f() public returns(bytes memory){
address payable addr1 = payable(msg.sender);
bytes memory params = new bytes(2);
params[0] = 0x21;
params[1] = 0x22;
bytes memory result = myopcode(addr1, 0x11, 0x12, params);
emit ReturnValue(addr1, result);
return result;
}
}
When I run that code I get invalid jump destination. So, what I need to do, to get my code work correctly?
I found a solution, it certainly looks stupid, but this case is already provided by the developers. All you need is utils().returnDataToArray().
I'm writing a function in Kotlin to retrieve items of type T from a database.
The user can specify an action to be invoked if no matching results are found, otherwise an IllegalArgumentException is thrown:
fun get(
...,
onNoneFound: () -> T = throw IllegalStateException("No matching results found")
): T {
...
return when (results.size) -> {
0 -> onNoneFound.invoke()
1 -> ...
else -> chooseResult(...)
}
}
The issue I'm having is that whenever the function is invoked, it seems that the IllegalStateException is thrown before the function body is executed.
In a way, that makes sense, and I suppose a workaround could be:
fun get(
...,
onNoneFound: (() -> T)? = null
): T {
...
return when (results.size) -> {
0 -> if (onNoneFound == null) {
throw IllegalArgumentException("No matching results found")
} else {
onNoneFound.invoke()
}
1 -> ...
else -> chooseResult(...)
}
}
I was wondering if there is a more elegant/preferable solution to this problem - ideally where I do not have to make the function nullable and do a null check later. Is there a way of doing this with Kotlin's default argument syntax?
Edit:
It occurred to me that I can use the elvis operator for the null check which does make the code more elegant:
onNoneFound?.invoke() ?: throw IllegalArgumentException("No matching results found")
But I'm still curious if Kotlin has a built-in way of doing this without the null check.
You shouldn't build the exception directly. Try:
fun get(
...,
onNoneFound: () -> T = { throw IllegalStateException("No matching results found") }
): T {
...
return when (results.size) -> {
0 -> onNoneFound.invoke()
1 -> ...
else -> chooseResult(...)
}
}
The problem is that throw IllegalStateException(...) is a perfectly fine expression of type () -> T, just as it is an expression of any other type; but it throws the exception immediately, what you want is a lambda which will throw the exception when invoked. And that's { throw IllegalStateException(...) } in Kotlin, as
Roger Lindsjö's answer says.
Hopefully my title explains it but I need a function that will take 3 arguments (two numbers and an operator [*, +, /, -]), then compute the result.
Something like this:
function evaluateExpression (firstNum, secondNum, operator) {
...
return ...;
}
evaluateExpression (35, 7, '/'); // should return 5
Pseudocode:
evaluateExpression( first, second, op ) :
if op == "+" :
return first + second
else if op == "*" :
return first * second
... etc
else :
return error
One way:
if (operator === "+") { return firstNum + secondNum };
if (operator === "-") { return firstNum - secondNum };
if (operator === "/") { return firstNum / secondNum };
if (operator === "*") { return firstNum * secondNum };
if (operator === "%") { return firstNum % secondNum };
Another way:
switch (operator) {
case "+" : return firstNum + secondNum;
case "-" : return firstNum - secondNum;
case "/" : return firstNum / secondNum;
case "*" : return firstNum * secondNum;
case "%" : return firstNum % secondNum;
}
If you are using javascript, this could be another way:
eval(firstNum + operator + secondNum);
Even in python, you can use the eval method. Just convert the operands to strings and call the function.
evaluateExpression( first, second, op ) :
return eval(str(first) + op + str(second))
Why isn't std.algorithm.reduce in Phobos pure? Is it an unfixed Issue or is there a reason why it can't be?
Has this something todo with the question:
"What does a pure function look like"
Andrei asked in the final lecture at DConf 2013?
See: http://forum.dlang.orgthread/20120306224101.GA30389#quickfur.ath.cx
I want the function sparseness in the following code to be pure. I guess I could always replace reduce with a foreach loop for now right?
import std.algorithm: reduce, min, max;
import std.typetuple: templateAnd;
import std.traits: isArray, Unqual;
import std.range: ElementType, isInputRange, isBidirectionalRange, isFloatingPoint;
//** Returns: true if $(D a) is set to the default value of its type. */
bool defaulted(T)(T x) #safe pure nothrow { return x == T.init; }
alias defaulted untouched;
/** Returns: Number of Default-Initialized (Zero) Elements in $(D range). */
size_t sparseness(T)(in T x, int recurseDepth = -1) #trusted /* pure nothrow */ {
import std.traits: isStaticArray;
static if (isStaticArray!T ||
isInputRange!T) {
import std.range: empty;
immutable isEmpty = x.empty;
if (isEmpty || recurseDepth == 0) {
return isEmpty;
} else {
const nextDepth = (recurseDepth == -1 ?
recurseDepth :
recurseDepth - 1);
static if (isStaticArray!T) { // TODO: We can't algorithms be applied to static arrays?
typeof(return) ret;
foreach (ref elt; x) { ret += elt.sparseness(nextDepth); }
return ret;
} else {
import std.algorithm: map, reduce;
return reduce!"a+b"(x.map!(a => a.sparseness(nextDepth)));
}
}
} else static if (isFloatingPoint!T) {
return x == 0; // explicit zero because T.init is nan here
} else {
return x.defaulted;
}
}
unittest {
assert(1.sparseness == 0);
assert(0.sparseness == 1);
assert(0.0.sparseness == 1);
assert(0.1.sparseness == 0);
assert(0.0f.sparseness == 1);
assert(0.1f.sparseness == 0);
assert("".sparseness == 1);
assert(null.sparseness == 1);
immutable ubyte[3] x3 = [1, 2, 3]; assert(x3[].sparseness == 0);
immutable float[3] f3 = [1, 2, 3]; assert(f3[].sparseness == 0);
immutable ubyte[2][2] x22 = [0, 1, 0, 1]; assert(x22[].sparseness == 2);
immutable ubyte[2][2] x22z = [0, 0, 0, 0]; assert(x22z[].sparseness == 4);
}
Update:
I decided on instead using isIterable and foreach instead of the above, as this works just aswell for me right now and makes things #safe pure nothrow. I see no need right now to use higher order functions to solve this problem. I also found Davids Simchas' upcoming std.rational very natural to use here:
import rational: Rational;
/** Returns: Number of Default-Initialized (Zero) Elements in $(D x) at
recursion depth $(D depth).
*/
Rational!ulong sparseness(T)(in T x, int depth = -1) #safe pure nothrow {
alias R = typeof(return); // rational shorthand
static if (isIterable!T) {
import std.range: empty;
immutable isEmpty = x.empty;
if (isEmpty || depth == 0) {
return R(isEmpty, 1);
} else {
immutable nextDepth = (depth == -1 ? depth : depth - 1);
ulong nums, denoms;
foreach (ref elt; x) {
auto sub = elt.sparseness(nextDepth);
nums += sub.numerator;
denoms += sub.denominator;
}
return R(nums, denoms);
}
} else static if (isFloatingPoint!T) {
return R(x == 0, 1); // explicit zero because T.init is nan here
} else {
return R(x.defaulted, 1);
}
}
If you change nextDepth to immutable rather than const then sparseness will be pure.
I believe this is a bug, it may be to do with the closure being passed to reduce capturing nextDepth, and for some reason thinking it may be mutable because it is const. Values declared as const are however identical to those declared as immutable -- the difference only manifests itself with indirections -- so I believe it is an error.
You may want to file a minimal repro case as a bug.
(it cannot be nothrow however, because reduce can, in fact, throw)
How do I create this function which returns true if a number is 5 to an anonymous function:
def yeah_five(p: Int): Boolean = p == 5
thanks?
Short notation for anonymous functions:
(p: Int) => (p == 5);
Long version:
new Function1[Int] {
def apply(p: Int): Int = p == 5
}
You want a function that takes an Integer and returns a Boolean
(p: Int) => (p == 5);
Read through the tutorial on anonymous functions.
I guess the shortest way to write it would be like so:
val f: Int => Boolean = (_ == 5)
Of course, depending on the context you can loose the type annotation:
List(1, 2, 3, 5, 4, 5).filter(_ == 5)
=> List(5, 5)
As per #Senia's observation you can be even more succint with 5== wich transforms the == method of the object 5 to a function.
val g: Int => Boolean = 5==
List(1, 2, 3, 5, 4, 5).filter(g) => List(5, 5)
In case you are want to turn that already declared method into a function, do this
yeah_five _