Conflict between GroovyTruth and implicit constructor - groovy

I have noticed some conflict between implicit constructor and GroovyTruth.
Consider following code
assert new File('/') == ['/'] as File
assert Boolean.TRUE == ["false"] as Boolean
First line is implict call of File(String) constructor.
Second line simply returns true, because list is not empty. But it can(should?) call Boolean(String) constructor with different result value(false).
Is it bug, documented feature or smth. else? Should I report it as bug?

When you do:
['false'] as Boolean
It ends up going through DefaultTypeTransformation.castToType, which calls castToBoolean which as you can see checks for null, then calls asBoolean on the Collection type which just checks it's not empty
With the File example, it falls through to the bottom of castToType and just tries to invoke the constructor with the contents of the list
I wouldn't say this is a bug, but it's definitely an idiosyncrasy of Groovy that has to be taken in to account (and changing it now would be a massive break with compatibility)

Related

GEB: Disable implicit assertions in waitFor block

I have a waitFor{} block with several lines inside:
waitFor(timeOutSeconds) {
jobRow.clickUpdate()
processDialog.waitIfShown()
jobRow.statusCell.text() == status.value
}
According to The Book of GEB:
Any calls to refreshWaitFor() method have implicit assertions added to
each expression in the bloc passed to it just like for waitFor()
method calls.
The problem is that processDialog.waitIfShown() can return false, and this is actually okay if the progress bar was not displayed.
I need the only last row to be verified for groovy truth, so now I'm writing processDialog.waitIfShown() || true to skip this expression verification. This works but looks odd.
Is there any flag or option to turn off implicit assertions in waiting blocks?
If you would like to disable implicit assertions for a specific waitFor() call then no, that's currently not supported out of the box. There is a number of workarounds, though:
implicit assertions can be disabled globally if you remove org.gebish:geb-implicit-assertions artifact from the compile classpath - it's a transitive dependency of geb-core and excluding transitive dependencies is relatively easy in all major build systems
implicit assertions are not applied on calls to void methods - if you wrap processDialog.waitIfShown() into a method having void as the return type then calls to that method will not be asserted
implicit assertions are only applied to waitFor() calls if closure literals are passed to them - if you assign your condition closure to a variable and then pass that variable to the waitFor() call then no statements in that closure will be implicitly asserted
If you believe that the above options/workarounds are insufficient then please feel free to raise an issue in the tracker.
If you look at more recent versions of geb's Page, you'll see they've added a getShouldVerifyAtImplicitly method, which can be overridden on your implementation of a Page to return false. Since it's groovy, it's as easy as just defining...
boolean shouldVerifyAtImplicitly = false
...anywhere in your Page class.

Why doesn't calling repr on type objects work as expected?

First, let me say that I agree that eval(repr(some_string)) is potentially a bad idea. But it is a thing that exists, and I have a specific question about it.
Why doesn't this work?
my_type = int
my_type_str = repr(int)
my_type_from_str = eval(my_type_str)
To clarify, I know specifically why the eval call fails. The command repr(int) produces a string which cannot be automatically interpreted. I guess my issue is that this isn't behaving as I expect... so either my expectation is faulty or the implementation is faulty. Which is it?
Side Note
There are some tricks that can be used to get around this default behavior, some obvious, some not. For instance, this:
my_type = int
my_type_str = my_type.__name__
my_type_from_str = eval(my_type_str)
assert my_type is my_type_from_str
This sets off my "hack" alert hardcore, and I don't like it (or other similar hacks, for instance parsing the string "<class 'int'>" with some home made function).
The documentation explains:
Return a string containing a printable representation of an object. For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a repr() method.
(emphasis mine)
So, it doesn't say that repr must always return valid Python code - sometimes it's not the case. Just another argument for not relying on it.

Erlang: Search through list for matching string

Hopefully this is what my problem is(having problem reading the error log that erlang prints). I'm trying to search through a list to find a matching string(PID from a client converted to a string) but it just results in a crash.
...
#7 ClientPID = pid_to_list(From),
#8 list:member(ClientPID, #server.users), % 'users' being a list in the record 'server'
...
The 'users' list in the 'server' record is just defined to users = [], if it helps.
Crash report:
** Reason for termination ==
** "{undef,[{list,member,[\"<0.568.0>\",2],[]}, {server,loop,2,[{file,\"server.erl\"},{line,8}]},
{genserver,loop,2,[{file,\"c:/Erlang/ServCli/genserver.erl\"}{line,13}]}]}"
Module is called lists not list. It's common mistake :)
And your argument are little off. You are using record, and proper usage look like this: VariableThatStoresRecord#record_name.filed_name. In your case it could be something like State#state.users (or just shorten State parameter in loop function to S if you don't like this double state).
What you are doing is actually a semantic suger, which returns on which element in record/tuple given field is stored (since all records are in fact tuples). In you case #state.users returns 2 (first element is record name, and I guess that users is first defined field in your record).
Regarding the error message. First thing is thing you get undef error. So it means that you are meking call to undefined function (which is quite common, since Erlang is dynamic language). Than you get list of tuples, which represents call-trace, from newest to oldest like this
[ { function call definition }
{ function call definition }
{ function call definition } ]
The first one is most interesting, since it is the call to undefined function. You can see that it is call to module list and function member. Other than that you can expect either actual arguments, or just arrity (those variables could be garbage collected already in erlang), and some information about function definition (like file and line number).
And from {list,member,[\"<0.568.0>\",2],[]} you can see that you are trying to call list:member function, with arguments "<0.568.0>" and 2. If you change your call to lists:member(ClientPID, Server#server.users) it should work.
Since most of the error messages are usually nested tuples/lists, which are hard to read if they are presented in one line. So what I do is copy them to my editor, split the one-liner into multiple lines, and than auto indent (emacs does this really great, and some editor can follow this lisp-like indention for Erlang).

Why does ATL COM map scanning code expect the first entry to be of _ATL_SIMPLEMAPENTRY type?

ATL provides a bunch of macros for creating so-called COM maps - chains of rules of how the QueryInterface() call behaves on a given object. The map begins with BEGIN_COM_MAP and ends with END_COM_MAP. In between the the following can be used (among others):
COM_INTERFACE_ENTRY, COM_INTERFACE_ENTRY2 - to ask C++ to simply cast this class to the corresponding COM interface
COM_INTERFACE_ENTRY_FUNC - to ask C++ to call a function that will retrieve the interface
Now the problem is I want to use COM_INTERFACE_ENTRY_FUNC for every interface I expose so that I can log all the calls - I believe it will help me debugging my component when it is deployed in the field. The implementation of CComObjectRootBase::InternalQueryInterface contains an ATLASSERT:
ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
which implies that the following is allright:
BEGIN_COM_MAP
COM_INTERFACE_ENTRY( IMyInterface1 )
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface2), 0, OnQueryMyInterface2 )
END_COM_MAP
since here the first entry results in _ATL_SIMPLEMAPENTRY type entry but the following is not:
BEGIN_COM_MAP
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface1), 0, OnQueryMyInterface1 )
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface2), 0, OnQueryMyInterface2 )
END_COM_MAP
since here the entry type will not be _ATL_SIMPLEMAPENTRY.
This makes no sense at all. Why am I enforced into having a "please, C++, do the static_cast" entry as the first entry of the COM map?
Upd: Resolved after many more hour of debugging, answer added.
Inside ATL there's AtlInternalQueryInterface() that actually does scan the COM map. Inside it there's this code:
if (InlineIsEqualUnknown(iid)) // use first interface
{
IUnknown* pUnk = (IUnknown*)((INT_PTR)pThis+pEntries->dw);
// call AddRef on pUnk, copy it to ppvObject, return S_OK
}
this code actually relies on the first entry of the table being of _ATL_SIMPLEMAPENTRY type since it expects that _ATL_INTMAP_ENTRY::dw stores an offset from the current object this pointer to the necessary interface. In the use cited in the question if the first entry is this one:
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface1), 0, OnQueryMyInterface1 )
the entry will be of wrong type, but the _ATL_INTMAP_ENTRY::dw will be zero (second parameter to the macro) and the code will happily work each time returning this pointer as IUnknown*. But if the second macro parameter which corresponds to a pass this value into the function specified as the third parameter variable is not zero the program will use that value as the offset and could run into undefined behaviour.

IDynamicObject implementation ignores multiple property invocations

I've implemented IDynamicObject in C# 4, return a custom MetaObject subclass that does simple property getter/setter dispatch to a Dictionary. Not rocket science.
If I do this:
dynamic foo = new DynamicFoo();
foo.Name = "Joe";
foo.Name = "Fred";
Console.WriteLine(foo.Name);
Then 'Joe' is printed to the console... the second call to the 'Name' setter is never invoked (never steps into my custom dispatcher code at all).
I know the DLR does callsite caching, but I assumed that wouldn't apply here. Anyone know what's going on?
Whatever MetaObject you're returning from (Bind)SetMember will be cached and re-used in this case. You have 2 dynamic sites doing sets. The 1st call will cache the result in an L2 cache which the 2nd site will pick up before asking you to produce a new rule.
So whatever MetaObject you're returning needs to include an expression tree that will update the value. For example it should do something like:
return new MetaObject(
Expression.AssignProperty(this.Expression, value.Expression),
Restrictions.TypeRestriction(this.Expression, this.Value.GetType());

Resources