How to handle return types with multiple fields - ocaml

I am calling a method "get_text" on GText.buffer detailed here http://oandrieu.nerim.net/ocaml/lablgtk/doc/GText.buffer.html
let text = textView#buffer#get_text in
However as get_text returns multiple values, when I try to use my variable "text" as a string, for example
textView2#buffer#set_text text;
I get the following error message:
Error: This expression has type
?start:GText.iter ->
?stop:GText.iter -> ?slice:bool -> ?visible:bool -> unit -> string
but an expression was expected of type string
How can I access the string being returned by the method? In general, how can I separate the multiple values returned by a method so I can access and use them individually?

I just looked up your link to lablgtk - it looks like you are missing the ():
let text = textView#buffer#get_text () in ...
The problem with this kind of error is that you are using a (curried) function where a string is required, and the message about the type error sounds kind of "long winded" and not to the point.

Related

Faulty query of list object and parameter

I'am a new coder and try to code a Loginterminal.
I want to make a query to check if the parameter username is the same as the username from the list. However, I get an error message and I don't understand where the problem is.
if (var = user.front().getNutzername()) { }
Error report: The expression must have a boolean type (or be convertible to a boolean type).

Use a method on a StateNotifier Riverpod for changing a bool [duplicate]

In the context of a Flutter 2.0.5 app whose state I'd like to manage with Riverpod, I thought I can declare a StateNotifierProvider like this:
import 'package:flutter_riverpod/flutter_riverpod.dart';
final counterProvider = StateNotifierProvider<CounterStateNotifier>((ref) => CounterStateNotifier());
class CounterStateNotifier extends StateNotifier<int> {
CounterStateNotifier([int count = 0]) : super(count);
void increment() => state++;
}
But Android Studio (and later the Dart compiler as well) complains about the line where I declare the counterProvider variable:
The type 'StateNotifierProvider' is declared with 2 type parameters, but 1 type arguments were given.
Removing the <CounterStateNotifier> type parameter in StateNotifierProvider<CounterStateNotifier> removes the error. However, attempting to read the provider and call its increment method (setting () => context.read(counterProvider).increment() as the onPressed of an ElevatedButton, then pressing the button) gives the following runtime error:
'increment'
method not found
Receiver: 0
Arguments: []
Why is context.read(counterProvider) returning the int state instead of the notifier? And what is the reason behind the type parameter error mentioned in the first part of my question?
I should mention that I'm running my app on the web (with flutter run -d Chrome).
As of Riverpod 0.14.0, State is the default value exposed by StateNotifierProvider.
The syntax for declaring your StateNotifierProvider is now as follows:
final counterProvider = StateNotifierProvider<CounterStateNotifier, int>((ref) => CounterStateNotifier());
Accessing functions now requires adding .notifier (accessing the StateNotifier itself):
context.read(counterProvider.notifier).increment();
And like you've noticed, you now access the state like so:
final count = context.read(counterProvider);
More on the changes here.
You may also use dynamic to accept any type if value for the StateNotifierProvider
final modelProvider =
StateNotifierProvider.autoDispose<ModelClassName, dynamic>(
(ref) => ModelClassName());

Create Granite model from JSON params

What I would like to have happen: Someone can make a post request to users/new with parameters, and I would like to create a User object from the JSON parameters.
In the readme, it gives this example:
foo = Foo.from_json(%({"name": "Granite1"}))
But when I try to do this I get this compile-time error:
in /usr/local/Cellar/crystal/0.26.1/src/json/pull_parser.cr:13: no
overload matches 'JSON::Lexer.new' with type Hash(String, Array(JSON::Any) | Bool | Float64 | Hash(String, JSON::Any) | Int64 | String | Nil)
Overloads are:
- JSON::Lexer.new(string : String)
- JSON::Lexer.new(io : IO)
- JSON::Lexer.new()
#lexer = Lexer.new input
^~~
Here is what env.params.json looks like when logged to the console:
{"name" => "test",
"username" => "tester",
"email" => "test",
"password" => "test"}
Any help would be much appreciated.
The compiler is steering you in the right direction here. It looks like you're passing in a variable that, at compile-time, has the type Hash(String, V) where V is one of the types
Array(JSON::Any)
Bool
Float64
Hash(String, JSON::Any)
Int64
String
Nil
What it's expecting is a String (or an IO object, which is similar to a String) of JSON. That's what you have in the example. %(foo) is another way to create the String "foo" (See "Percent string literals" in the guide for more info). They're using it here because it allows you to avoid escaping the double quotes used in the JSON.
Based on the compile-time type that Crystal has given your parameter, my guess is that it's already been converted from JSON into a Crystal Hash. Double-check that you're not parsing it twice.
Without seeing the source, there's not much more information I can provide, but I hope that helps.

RSpec it block with variable name

I have a function get_type that returns a string given an int:
def get_type(integer)
types = [...]
return types[integer]
end
When testing with RSpec, I tried doing the following:
describe 'function' do
context 'on valid input'
let(:input){ 2 }
let(:type){ 'large' }
let(:result){ get_type input }
it{ expect(result).to eq(type) }
end
end
However, this gives the message:
function on valid input should eq "large"
without any mention to the input, thus sounding like the function should always return "large".
How should this message be changed to say something like:
function on valid input should eq type
or another meaningful message? I could name the it block:
it 'should have the correct type' do
expect(result).to eq(type)
end
but is there a nicer way to do this without essentially typing out the test twice?
I think the unhelpful message should be considered a smell - you're headed down a road where every test is just expect(result).to eq(expected) with a wall of let. To my mind this is overuse of let - I don't think you gain anything over
describe 'function' do
context 'on valid input' do
it{ expect(get_type(2)).to eq('large') }
end
end
Which would produce a more helpful failure message. I would keep let for when the expressions are more complex or when I can give them a better name (eg a hash of attributes called valid_attributes)

Dart Error : Class '_Template' has no instance method 'render' with matching arguments

When the below chunk of DART program is executed, error "Breaking on exception: Class '_Template' has no instance method 'render' with matching arguments." is thrown.
var source = '{{#data}}<div>{{title}},{{time}}</div>{{/data}}';
var template = mustache.parse(source);
var output;
output = template.render({'guide_data_cell': [{'title': 'friends','time': '10:00 PM'}]});
Please help if I missed any syntax.
According to the package:mustache docs, render() requires both a values map and a StringSink, or you can use renderString() which only requires a values map.
If you're using the Dart Editor, it should show a warning on the call to render() for the mismatched arguments.