Re: Strange behavior of opEquals for structs

2019-06-19 Thread harfel via Digitalmars-d-learn

On Wednesday, 19 June 2019 at 17:15:31 UTC, Ali Çehreli wrote:

On 06/19/2019 08:28 AM, harfel wrote:

You need to define toHash() member function as well:

  https://dlang.org/spec/hash-map.html#using_struct_as_key

Ali


Thanks Ali,

This fixed my problem, of course. Amazing that such a beginner's 
mistake still receives attention by one of the gurus :-)


harfel


Strange behavior of opEquals for structs

2019-06-19 Thread harfel via Digitalmars-d-learn
I am trying to overload opEquals for a struct. The struct will 
hold class objects that define their own opEquals so the default 
bitwise comparison is not good for me.
Everything works nicely if I compare the structs directly. Yet 
when they are used as keys in an associative array, the code 
throws an exception that I do not understand.


My minimal code example is this:

debug import std.stdio;

struct Foo(T) {
int[T] content;

bool opEquals(const(Foo!T) that) {
debug writeln("opEquals called");
return true;
}

alias content this;
}

class Bar { }

void main()
{
Foo!Bar a = Foo!Bar();
Foo!Bar b = Foo!Bar();
assert(a == b);

debug writeln("This works");

Foo!Bar[int] x = [1: Foo!Bar()];
x[1][new Bar] = 1;
Foo!Bar[int] y = [1: Foo!Bar()];
y[1][new Bar] = 1;

assert(x == y);

debug writeln("This does not work");
}


Here is what I get (using DMD64 D Compiler v2.086.0):

opEquals called
This works
object.Error@(0): TypeInfo.equals is not implemented

??:? bool object._xopEquals(const(void*), const(void*)) [0x49e844]
??:? const pure nothrow @trusted bool 
object.TypeInfo_Struct.equals(const(void*), const(void*)) 
[0x49dcdb]

??:? _aaEqual [0x4a850b]
source/app.d:29 _Dmain [0x46c52f]
Program exited with code 1

Strange thing is that everything works nicely (but produces the 
expected AssertionError) if I comment out Foo.opEquals. What is 
the error message telling me and how can I fix it?


Thanks!!


saving std.random RNG state

2018-12-17 Thread harfel via Digitalmars-d-learn
I am looking for a way to serialize/deserialize the state of the 
std.random.Random number generator, ideally using orange 
(https://github.com/jacob-carlborg/orange) or another 
serialization library. From looking at the module source code, I 
understand how to seed a random number generator with the state 
of another, but I do find a way to access the RNG's state, since 
it is hidden away in a private attribute. What is the recommended 
solution for this? Thanks in advance!


Re: pyd: implementing __hash__ and __str__ for PyD wrapped classes

2017-04-05 Thread harfel via Digitalmars-d-learn

On Wednesday, 5 April 2017 at 11:39:47 UTC, Nicholas Wilson wrote:

On Wednesday, 5 April 2017 at 09:31:09 UTC, harfel wrote:

Dear all,

[...]

Following the documentation and code examples, I got the basic 
functionality working. However, I am struggling with 
implementing the magic functions __str__ and __hash__ of the 
extension class. >> Is there a way to declare these slots in 
PyD? I noticed that Repr does this for __repr__ and the 
operator overloads do this of course for their respective 
slots, but I could not find anything for __hash__ and __str__.


[...]


I haven't chased the source but most likely __hash__ and 
__str__ will be "magically" generated from toHash() and 
toString() respectively (both methods of Object, 
see:https://dlang.org/phobos/object.html#.Object).


Unfortunately, this does not seem to be the case, as my D classes 
do override
toHash and toString, but they are not called by the corresponding 
python classes.


pyd: implementing __hash__ and __str__ for PyD wrapped classes

2017-04-05 Thread harfel via Digitalmars-d-learn

Dear all,

Relatively new to D in general and PyD in particular, I am trying 
to wrap some D classes I wrote for use in Python.


Following the documentation and code examples, I got the basic 
functionality working. However, I am struggling with implementing 
the magic functions __str__ and __hash__ of the extension class. 
My current approach was to implement them as ordinary member 
functions:



extern(C) void PydMain() {
module_init();

// Reaction
wrap_class!(PyReaction,
PyName!"Reaction",
Init!(MultiSet, MultiSet),
Property!(PyReaction.reactants),
Property!(PyReaction.products),
Repr!(PyReaction.repr),
Def!(PyReaction.py_str, PyName!"__str__"),   // XXX needs slot
Def!(PyReaction.py_hash, PyName!"__hash__"), // XXX needs slot
)();
}

but this does not work. In Python:

Python 2.7.12+ (default, Sep 17 2016, 12:08:02)
[GCC 6.2.0 20160914] on linux2
Type "help", "copyright", "credits" or "license" for more 
information.

from teest_module import *
r=Reaction({'a':1, 'b':1}, {'ab':1})
r.__hash__
0x7fc1c7f4a080>

r.__hash__()

1430289695L

hash(r)

8779391257096

According to related post for C++/SWIG 
(http://stackoverflow.com/questions/25199233/str-not-called-when-printing-c-class-wrapped-for-python-with-swig), the reason is that these magic methods need to be implemented as slots, rather than ordinary member functions.


Is there a way to declare these slots in PyD? I noticed that Repr 
does this for __repr__ and the operator overloads do this of 
course for their respective slots, but I could not find anything 
for __hash__ and __str__.


Any ideas?

Thanks!