How do Pony constructors work? - constructor

It doesn't look like the Pony language has made many inroads to stack overflow yet, but you've gotta start somewhere...
Here's the very limited info about Pony constructors, which isn't helping me understand what I'm seeing.
Here's an initial program:
class Wombat
let name: String
var _hunger_level: U64
new anon() =>
name = "Anon"
_hunger_level = 0
new create(name': String) =>
name = name'
_hunger_level = 0
new hungry(name': String, hunger': U64) =>
name = name'
_hunger_level = hunger'
actor Main
new create(env: Env) =>
env.out.print("Started.")
let wombat: Wombat = Wombat("Ernie")
let w: Wombat = createWombat()
env.out.print("Name: "+wombat.name)
env.out.print("Name: "+w.name)
fun createWombat(): Wombat =>
let w: Wombat = Wombat("Bert")
w
Let's rename the "create" constructor to "named":
new named(name': String) =>
name = name'
_hunger_level = 0
... and I see error:
Error:
/src/main/main.pony:22:26: couldn't find 'create' in 'Wombat'
let wombat: Wombat = Wombat("Ernie")
... which suggests that all constructors are not created equal. Huh...?
So, let's undo that change.
Now let's try using the zero-arg constructor:
let wombat: Wombat = Wombat()
let w: Wombat = createWombat()
... and now I see:
Error:
/src/main/main.pony:22:33: not enough arguments
let wombat: Wombat = Wombat()
^
It's ignoring that constructor.
So, let's rename the first two constructors:
new create() =>
name = "Anon"
_hunger_level = 0
new named(name': String) =>
name = name'
_hunger_level = 0
... and now I see:
Error:
/src/main/main.pony:22:26: couldn't find 'apply' in 'Wombat'
let wombat: Wombat = Wombat()
No idea what that means.

Thank you to Chris Double on the Pony mailing list.
The answer is in the Syntactic Sugar docs. We simply need to specify which constructors we're running. So I changed the anon instantiation to:
let wombat: Wombat = Wombat.anon()

Related

Unhandled Exception: type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<DateTime, List<Account>>' in type cast

I am trying to convert data decoded from json to Map<DateTime,List
Here is the Code:
var encodingaccounts = json.decode(gettingAccounts!);
var encodedAccounts = encodingTasks.map((dateTime, Accounts) {
List<Account> convertedAccountsType = [];
for (var Account in Accounts) {
String _summary = Account['summary'];
String _description = Account['description'];
String _category = Account['category'];
bool _isDone = Account['isDone'];
convertedaccountsType.add(Account(_summary,
category: _category, description: _description, isDone: _isDone));
}
return MapEntry(DateTime.parse(dateTime), convertedaccountsype);
});
_accounts = encodedAccounts as Map<DateTime, List<Account>>;
But following error occurs:
[ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: type
'_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<DateTime,
List<Account>>' in type cast
I have checked encoding.map() returns correct datatype(Map,List) but still this error appears.
You can use Dart special Method of Map.from()
Just Like:
_accounts = Map<DateTime,List<Account>>.from(encodedAccounts);
Here is the complete code:
var encodingaccounts = json.decode(gettingAccounts!);
var encodedAccounts = encodingTasks.map((dateTime, Accounts) {
List<Account> convertedAccountsType = [];
for (var Account in Accounts) {
String _summary = Account['summary'];
String _description = Account['description'];
String _category = Account['category'];
bool _isDone = Account['isDone'];
convertedaccountsType.add(Account(_summary,
category: _category, description: _description, isDone: _isDone));
}
return MapEntry(DateTime.parse(dateTime), convertedaccountsype);
});
w_accounts = Map<DateTime,List<Account>>.from(encodedAccount);
It sometimes helps to add types to map as here:
final _accounts =
et.map<DateTime, List<Account>>((dateTime, accounts) => MapEntry(
DateTime.parse(dateTime),
accounts
.map<Account>((e) => Account(
e['summary'],
e['category'],
e['description'],
e['isDone'],
))
.toList()));
print(_accounts.runtimeType);
Prints _InternalLinkedHashMap<DateTime, List<Account>> as expected. (Note that I changed the constructor of Account for simplicity in this example.)

How to verify if a data source name is valid?

I am using OptsBuilder passing a data source name to create a connection pool:
let mut opts = mysql::OptsBuilder::from_opts(dsn);
opts.stmt_cache_size(0);
let pool = mysql::Pool::new_manual(1, 3, opts).expect("Could not connect to MySQL");
If I pass an invalid DSN, the code panics:
thread 'main' panicked at 'URL ParseError { relative URL without a base }', ', /path/.cargo/registry/src/github.com-1ecc6299db9ec823/mysql-16.0.2/src/conn/opts.rs:827:25
How can I handle the error or verify in advance to prevent panicking?
You can create the Opts with from_url, so that you are sure that it won't fail after that:
let opts = match Opts::from_url(dsn) {
Ok(opts) => opts,
Err(e) => panic!(),// manage error
};
let mut opts = mysql::OptsBuilder::from_opts(opts);
opts.stmt_cache_size(0);
let pool = mysql::Pool::new_manual(1, 3, opts).expect("Could not connect to MySQL");

F# Unit Test Error: xUnit.net / TestDriven.Net

So the following I got from Pluralsight and the chap presenting the course apparently runs the code without a hitch, however, when I run it, I get the error message:
"Test failed ‘T:Messaging’ : Couldn’t find type with name ‘Messaging’"
Test failed 'T: Couldn't find type with name
Any Ideas (appreciated)?
namespace Ploeh.Samples
open System
module Messaging =
type Envelope<'a> = {
Id : Guid
Created : DateTimeOffset
Item : 'a }
let envelop getId getTime item = {
Id = Guid "1CF889F8-201F-44DF-BC86-77227651D3EE"
Created = DateTimeOffset.MinValue
Item = item }
module MessagingTests =
open Xunit
type Foo = { Text : string; Number : int }
[<Fact>]
let ``enevelope returns correct results`` () =
let getId _ = Guid "1CF889F8-201F-44DF-BC86-77227651D3EE"
let getTime _ = DateTimeOffset( 636322011751405346L,
TimeSpan.FromHours(-4.0) )
let item = { Text = "Bar"; Number = 42 }
let actual = Messaging.envelop getId getTime item
Assert.Equal ( Guid "1CF889F8-201F-44DF-BC86-77227651D3EE",
actual.Id )
Assert.Equal ( DateTimeOffset( 636322011751405346L,
TimeSpan.FromHours(-4.0) ),
actual.Created )
Assert.Equal ( item, actual.Item )
I managed to get it working by separating the tests into a separate file and top-level module. For some reason, anything other than this `setup' does not work, e.g., separate file but in a lower-level module, or namespace and module declarations separately ... I am not sure whether this is something specific to say my target being .Net 4.7 rather than whatever used by the instructor or an issue with Visual Studio 2017, or something else. It seems that TestDriven.Net takes issue with the namespace/module system and gets confused by them ...
In the first file:
namespace Ploeh.Samples
open System
module Messaging =
type Envelope<'a> = {
Id : Guid
Created : DateTimeOffset
Item : 'a }
let envelop getId getTime item = {
Id = Guid "1CF889F8-201F-44DF-BC86-77227651D3EE"
Created = DateTimeOffset.MinValue
Item = item }
And in the second file:
module Ploeh.Samples.MessagingTests
open System
open Messaging
open Xunit
type Foo = { Text : string; Number : int }
[<Fact>]
let ``enevelope returns correct results`` () =
let getId _ = Guid "1CF889F8-201F-44DF-BC86-77227651D3EE"
let getTime _ = DateTimeOffset( 636322011751405346L,
TimeSpan.FromHours(-4.0) )
let item = { Text = "Bar"; Number = 42 }
let actual = Messaging.envelop getId getTime item
Assert.Equal ( Guid "1CF889F8-201F-44DF-BC86-77227651D3EE",
actual.Id )
Assert.Equal ( DateTimeOffset( 636322011751405346L,
TimeSpan.FromHours(-4.0) ),
actual.Created )
Assert.Equal ( item, actual.Item )

Unable to cast object of type 'System.Collections.Generic.List`1 [<>f__AnonymousType6`65[System.String,System.Decimal,System.Nullable`1

I'm trying to hit my head to get out of this issue in which I'm not able to convert System.Collections.Generic.List to IEnumerable, below is my code :
IEnumerable<PY_History_TransactionTAB> FilteredReport;
var ReportData = db.PY_History_TransactionTAB
.Where(x => x.SystemCode == SysCode)
.GroupBy(x => x.EmployeeCode);
FilteredReport = (IEnumerable<PY_History_TransactionTAB>)ReportData.Select(x => new
{
EmployeeCode = x.Key,
H_SalaryDays = x.Sum(y => y.H_SalaryDays ?? 0),
H_NET_Overtime = x.Sum(y => y.H_NET_Overtime),
H_Overtime_Amount = x.Sum(y => y.H_Overtime_Amount),
H_SL_Breakup1 = x.Sum(y => y.H_SL_Breakup1 ?? 0),
H_SL_Breakup2 = x.Sum(y => y.H_SL_Breakup2 ?? 0),
H_SL_Breakup3 = x.Sum(y => y.H_SL_Breakup3 ?? 0),
H_OT_Allowance1 = x.Sum(y => y.H_OT_Allowance1 ?? 0),
H_OT_Allowance2 = x.Sum(y => y.H_OT_Allowance2 ?? 0),
H_OT_Allowance3 = x.Sum(y => y.H_OT_Allowance3 ?? 0),
H_OT_Allowance4 = x.Sum(y => y.H_OT_Allowance4 ?? 0),
H_OT_Allowance5 = x.Sum(y => y.H_OT_Allowance5 ?? 0)
}).ToList();
When I run the application, it throws a runtime exception System.InvalidCastException at point of assignment to FilteredReport variable, by saying :
{"Unable to cast object of type 'System.Collections.Generic.List1[<>f__AnonymousType665
[System.String,System.Decimal,System.Nullable1[System.Decimal],System.Nullable1[System.Decimal],
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal
,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal,
System.Decimal,System.Decimal,System.Decimal,System.Decimal,System.Decimal]]' to type 'System.Collections
.Generic.IEnumerable`1[HrAndPayrollSystem.Models.PY_History_TransactionTAB]'."}
So, what I get is that I'm not going right, I need to find a right way, What should I do to get rid of this issue or what is the right way to convert a List to IEnumerable? Any Help will be deeply appreciated, Thanks in Advance!
Update:
Ok, René Vogt's answer is correct for the above issue, but then I encounter an another Exception System.NotSupportedException at the same point saying :
The entity or complex type
'HrAndPayrollSystem.Models.PY_History_TransactionTAB'
cannot be constructed in a LINQ to Entities query.
How should I resolve it?
The reason is that you return an List of an anonymous type. So this List<anonymousType> is a totally different type than a IEnumerable<HrAndPayrollSystem.Models.PY_History_TransactionTAB>.
So you need to change your Select call to something like:
FilteredReport = (IEnumerable<PY_History_TransactionTAB>)ReportData.Select(x =>
new PY_History_TransactionTAB // specify type!!
{
EmployeeCode = x.Key,
// shortened for brevity... set properties appropriatly
}).ToList();
Now the returned list is of type List<PY_History_TransactionTAB> which implements IEnumerable<PY_History_TransactionTAB>.

Scala Lift - Dynamically called function

I've got a function which loads various models, and currently have this kind of setup:
if(message == "user") {
var model = User.findAll(
("room" -> "demo")
)
} else if (message == "chat") {
var model = Chat.findAll(
("room" -> "demo")
)
}
This is really clunky as I aim to add lots more models in future, I know in javascript you can do something like this:
var models = {
"user" : load_user,
"chat" : load_chat
}
Where "load_user" and "load_chat" would load the respective models, and so I can streamline the whole thing by doing:
var model = models[message]();
Is there a way I can do something similar in Scala, so I can have a simple function which just passes the "message" var to a List or Object of some kind to return the relevant data?
Thanks in advance for any help, much appreciated :)
In Scala you can do:
val model = message match {
case "user" => loadUser() // custom function
case "chat" => loadChat() // another custom function
case _ => handleFailure()
}
You can as well work with a Map like you did in your JavaScript example like so:
scala> def loadUser() = 1 // custom function
loadUser: Int
scala> def loadChat() = 2 // another custom function
loadChat: Int
scala> val foo = Map("user" -> loadUser _, "chat" -> loadChat _)
foo: scala.collection.immutable.Map[java.lang.String,() => Int] = Map(user -> <function0>, chat -> <function0>)
scala> foo("user")()
res1: Int = 1
Pay attention to the use of "_" in order to prevent evaluation of loadUser or loadChat when creating the map.
Personally, I'd stick with pattern matching.