Pharo: #subclass:instanceVariables... message personalized - metaprogramming

I am fighting against the Object message #subclass:instanceVariableNames:classVariableNames:poolDictionaries:category, in order to manipulate subclasses of an specific class.
I have RareClass with a class method #subclass:coposes...etc and want to do:
RareClass
subclass: #RareSubclass
composes: #SomeMagic
instanceVariableNames: ''
classVariableNames: ''
in the browser.
whether this method should return a class, (and i think it does) it is not working at all, im getting parsing errors when i try to 'save'...

I guess you are using OmniBrowser with the Refactoring Engine loaded?
The Refactoring Engine enforces the standard class templates to enable undo on any action performed in the browser. Obviously that cannot work with custom class definitions.
As a workaround you can do one of the following:
Use the traditional browser that has no undo functionality (evaluate Browser open),
Get rid of the refactoring functionality in OmniBrowser by unloading the package "OB-Reactory", or
Update the code in RBAddClassChange to support your use case.

Related

How to get UIVisualizer to use the View Model passed to it

I'm attempting to create view/viewModel pair to act as a MessageBox replacement which will be called by the UIVisualizer Service. The viewModel has five different constructors, one being the default, and the others to define the different attributes of the MessageBox(e.g. Type, Image, Message, Title, etc.). I will be creating the viewModel using one of the four non-Default constructors each time I desire a MessageBox to popup. I am doing this versus using the built-in MessageService is because I'm using third party controls for my application and I want the MessageBox look-and-feel to match the rest of the application.
My problem is that even though I'm creating the viewModel, Catel is not using the viewModel I pass in to UIVisualizer, but is creating a new viewModel from the default constructor.
Does anybody know how to get this behavior to stop.
The best thing to do is create your own version of the IMessageService (create new class deriving from MessageService and override the Show method).
Catel should re-use the passed in view model. If you think you have found a bug, please report it at http://www.catelproject.com/support/issue-tracker

Is there a way to use a javascript object as a custom control property?

I'm currently building a custom control to be used as an application's view navigator (classic OneUI style). First of all: this is a 8.5.3 based project, and unfortunately there's no way to use Extlib stuff or other extensions / plug-ins. So we have to build all the tricky stuff ourselves using only what came "out-of-the-box" with 8.5.3.
I'd llike to build my navigator using a repeat control containing <xp:link> controls. Datasource could be an array of javascript objects where each single object would look like this:
var navEntry = {"entryLabel" : "label-of-link",
"entryTarget" : "target-url-of-link",
"entryStyle" : "style-to-emphasize-selected-link"}
Each array element then would describe a single navigator entry.
Since the navigator will be used in all possible "DominoView" Xpages it yould make sense to build the array of JS objects at the Xpage level and then pass that info into the custom control.
I'm aware that there are multiple ways to do this, and one could be "Custom Control Properties". If there was a way to pass my JS object array.
(Hope I could make clear what I'm trying to do here...)
That object looks like a HashMap to me really. You should be able to pass that in to a custom control via custom property if you use the type java.util.HashMap I'd think. You'll need to type it in I'm sure. I've passed custom objects in by using java.lang.Object.
The custom control will get loaded during the Page Load event, and usually properties have to be available at that point. If they're loaded during the Render Response phase, that's too late. So your SSJS object will need to be Compute on Page Load.
To use contents of a repeat control, you would need to set repeatControls=true, otherwise the repeat is only built during render response. Until then it's just a single set of controls with no data in them. However, Im pretty sure repeatControls="true" means you only get the number of rows you define. You can't change it via a pager.
You can manually define the type of the custom property. For a standard SSJS Object you use "com.ibm.jscript.std.ObjectObject", for a SSJS Array you use "com.ibm.jscript.std.ArrayObject" etc. As editor for the custom property, I set the string editor ("String value").

How to avoid constructor to be call twice when a page is define twice in a page

I am creating a winRt app. In which I am having a Home.xaml page which having a another page called Market.xaml. So for snapped mode the same code is repeated.
Now my itemListView (used for snapped) and itemGridView (for full view) both have this page (Market)
<views:Market x:Name="viewMarket"/>
And the constructor of this page is called twice which I not want.
So do I use some flag kind of thing or some better approach is there.
Thanks
So, let's talk about this:
XAML is basically a varying syntax to C#. So, when XAML references a control like your views:Market with <Views:Market />, you are actually putting in something like new Views.Market() in both places. Basically, invoking the class twice. Should the constructor not fire twice, the time-space continuum would split in half. Dogs and cats living together, the whole 9 yards.
But, more fundamental here, what is the purpose of the constructor in C#, or in a XAML class? Is to do expensive things that you would not want to repeat? No. The reason for this is because the completion of the constructor is necessary before the UI thread is released and allowed to render the control. The resulting effect is a UI hang.
Moreover, the C# constructor is a synchronous method. It cannot properly invoke or hold asynchronous operations. This means long-running or expensive tasks that should be invoked immediately, should not be invoked in the constructor because it would also require them to be synchronous and UI-blocking. It is because of these last two points I suspect your constructor is being misused.
The solution is in the XAML framework. The XAML Page pipeline includes the constructor (since it is a C# class and they all have it) but it also includes a Loaded event. In many cases, the hard work necessary to fill page controls is in the Loaded handler. This allows the page to render properly, then starts the long-running action that will ultimately and asynchronously update control content.
In WinRT, the Page pipeline also includes an OnNavigatedTo() virtual method in the base that you can override to the same effect. In the override you can include the hard work of talking to a service, deserializing from a file, or whatever you need to make your UI work. Both the Loaded event and the override can be asynchronous, and neither prevent rendering by freezing the constructor.
But, there's another thing to consider since we're in C# and that the rather common pattern called singleton that allows for us to reference a type in two different contexts but without creating a brand new class. This is accomplished by making the class constructor private, but exposing a public property usually called Instance that returns a single, shared instances in some static place.
That might solve your problem already. Then again, none of that is probably what you need. Assuming you already know all that, the quick answer is you can't prevent a constructor because a constructor is necessary to create a new instantiation of any class, including a XAML view. Instead, whatever you are trying to prevent being double might need to be a combination of the discussions above. An offloaded method, and a static reference to prevent duplicate efforts.
Something like this:
public class Market : UserControl
{
public Market()
{
Loaded += Market_Loaded;
}
static bool AlreadyLoaded = false;
void Market_Loaded(object sender, RoutedEventArgs e)
{
if (AlreadyLoaded)
return;
AlreadyLoaded = true;
// TODO: your work
}
}
But that might not do it for you because the static variable is scoped too large. Instead, you can control if it does the big operation with a dependency property you add to your control. With a boolean dependency property set to false, the second control knows not to do something. With it set to true, the first knows to go ahead. And, so on. This prevents all future use of the view or user control in your app from thinking it should not run because of the static property in the above solution. Then again, that might be perfect.
Best of luck!

Navigate between loosely related classes based on naming convention

In my current project we have many parts where we have something as follows:
var request = new ThingRequest {someId = };
ThingResponse response = dispatcher.Get<ThingResponse>(request);
Where dispatcher fetches a class with the name ThingRequestHandler that handles the actual logic.
public class ThingRequestHandler : RequestHandler<ThingRequest, ThingResponse>
This system is great for keeping it SOLID but I'm having trouble navigating easily.
Currently I use R# to goto class and -as I now the class name to follow convention- manually type the class name. This usually works but makes my head jump from thinking about the problem to thinking about a class name.
I would love to be able to navigate to my ThingRequestHandler from my dispatcher.Get line with one keystroke or click.
Is there a way Visual studio 2012, R# or any other plugin or macro would help me do this?
In R# 8+ they made a loads of improvements and especially to the navigation. They introduced CamelHumps which could be very useful in your case. For example you could navigate to ThingRequestHandler just by typing trh.

Is it possible to get intellisense to work with Geb page objects?

I am guessing this is more of a groovy issue due to the geb implementation, but I'm wondering if there is any way to get intellisense to work with the geb page objects. I am also new to Java/Groovy (primarily C# development in the past) so there could be some things I'm just not quite understanding. I'm using Intellij, but I'd be happy if there is any IDE that could give me what I wanted.
As far as I can tell, Geb's implementation is that they have a Browser Class with a Page property and any methods or properties that are executed without the context of a specific Page instance will at runtime trigger a MissingMethod or MissingProperty exception, which Geb handles and re-routes to a corresponding method or property in the Page class that is currently set via the Page property in the Browser Class.
What this means for development is that when we're creating test cases, the IDE is unaware of which page instance is the current Browser Page property, thus no intellisense.
We experimented with creating instances of the pages and explicitly calling them, and also making our helper functions within the page classes static, both of which led to other issues.
For our shop, this is pretty much a deal breaker, but before we give up I wanted to see if any Geb or Groovy experts could offer some advice on how to get intellisense working, or could give us an indication of whether it is even possible.
EDIT: I found within the geb documentation a section on Strong Typing and IDE support that looked promising: http://www.gebish.org/manual/current/ide-and-typing.html#ide_support however, the examples provided fail. I pasted the example directly from geb documentation below, with comments showing where/why it fails:
HomePage homePage = browser.to HomePage //browser.to returns null, so this fails
homePage.loginButton.click()
LoginPage loginPage = browser.at LoginPage //browser.at returns boolean so this fails
SecurePage securePage = loginPage.login("user1", "password1")
//The only thing that I got to work, which seems messy is:
browser.to HomePage
HomePage homePage = browser.page
homePage.loginButton.click()
Ok... So, I had an old version of Geb somehow being pulled from my gradle cache. After fixing that problem and actually using Geb 0.9.2, the documented usage worked correctly: http://www.gebish.org/manual/current/ide-and-typing.html#ide_support

Resources