As the title suggests, is there any documentation on the FlexBuilder "expressions" tab, and what expressions it can accept?
As far as I can tell, it can show the value of variables, but that's it: comparisons, function and method calls all fail:
alt text http://img.skitch.com/20100614-t1gpdbrn1qnwy2eqr3gnw54d1d.png
Edit: this is specific to FB3 — Flex Builder. Apparently FB4 — Flash Builder — is slightly less incompetent.
It depends if you're using FlexBuilder 3 or FlashBuilder 4. FB 3 has pitiful expressions capability. You can basically access variables and their member properties, period. And not always all the member properties.
FB 4 gives you the ability to evaluate real expressions, like
getStyle("vertical-align")
getStyle("vertical-align") + "foo"
parseInt(getStyle("padding-left"))
etc.
It shows the values of variables, and the results of expressions as at the current breakpoint in the debugger.
eg:
public function testMethod():void {
var a:String; // <-- Set breakpoint here
a = "Hello";
a = "World";
}
public function testMethodB():void {
var b:String = "Another String";
}
You can create an expression for a and watch the value change over time.
However, the variable must have a value within the context. For example, setting the breakpoint where indicated, and defining an expresssion for b would show an error.
Related
I am not able to understand extension function and use it in my project. Can anyone guide me here please?
From the docs - “Kotlin provides the ability to extend a class with new functionality without having to inherit from the class or use design patterns such as Decorator. This is done via special declarations called extensions.”
To understand this in an easy way, let’s consider the below example:
First things first.
Write 10 and then put a dot(.) after it and then try to write addTwoNumbers().
You’ll be getting errors at this stage as there is no property named addTwoNumbers() for an integer.
Now, write this method:
fun Int.addTwoNumbers(y: Int): Int = this.plus(y) //“this” corresponds to the integer number. (In this example, “this” refers to 10).
Notice how we are using Int.addTwoNumbers().
Let’s try to follow the same thing again:
Write 10.
Put a dot(.) after it.
Try to write addTwoNumbers().
And this time you’ll notice, it’s appearing as if this is the property of integer.
Check the below code:
fun main() {
val sum = 10.addTwoNumbers(20) //here “this” will be assigned “10” and “y” will be assigned “20”
println("sum: $sum")
}
This will print sum: 30 in the console.
This phenomena is known as “Extension Function”.
I'm new to meteor, and I've followed different tutorials that explain and use things differently.
There seems to be two ways of processing an event. For example, if I want to manage a click on a tag, both of the following methods work :
This one is present on the hello world meteor app
'click p'(event, instance) {
}
This one is the one used in the tutorial.
'click p': function(event){
}
Both work perfectly and if I use both the last one will be effective. The weird thing is the color is not the same (on sublime text), the second has usual js colors but the first one is only green, orange, and everything else is white (on monokai).
I'm tempted to use the second one for better visibility, but I know I should not make that choice base on that. Which one is correct, and when ?
Bottom line: it doesn't really matter if you only need the event.
There are 2 syntactic differences between the functions, but there is no substantial difference:
The notation that you are using:
funcName(arg1, arg2)
vs
funcName: function(arg1, arg2)
The highlighting coloration difference you see in your editor is probably related to the shorthand notation. This shorthand notation is a feature of ES2015, the relatively new version of JS, and both are functionally identical. It is just syntactic sugar.
The arity (number of arguments).
The function is used as an event handler as a callback. Due to the dynamic nature of JavaScript, any function can be called with any number of parameters. The parameters are being assigned to arguments based on the function's definition, and are also dynamically available to the called function via the arguments pseudo-array.
The callback will always be called with 2 parameters. In the version with 1 argument, the second parameter will not be bound to any identifier within the function. You can omit the second argument if you don't need the template instance.
I've been following GUI extensions and notice examples use either _isEnabled or isEnabled, without the underscore. Both seem to work to extend or possibly replace existing functionality.
isEnabled
For example, the PowerTools base class (which doesn't seem to "extend" existing functionality) has:
PowerTools.BaseCommand.prototype.isEnabled = function(selection, pipeline)
{
var p = this.properties;
if (!p.initialized)
{
this.initialize();
}
if (!this.isToolConfigured())
{
return false;
}
if (this.isValidSelection)
{
return this.isValidSelection(selection, pipeline);
}
return true;
};
A tool can use this base class and declare .isValidSelection, for example:
PowerTools.Commands.CountItems.prototype.isValidSelection =
function (selection) { ... }
_isEnabled
I see Anguilla uses ._isEnabled for existing functionality (in Chrome's console in numerous places in the code). For example, WhereUsed has:
Tridion.Cme.Commands.WhereUsed.prototype._isAvailable =
function WhereUsed$_isAvailable(selection) ...
Private functions?
I'm familiar with a preceding underscore being a naming convention for private variables. Are the _isEnabled and other functions that start with an underscore "private?" If so, then
How should we extend (add additional functionality to existing code) these functions?
How should we replace (not have existing code run, but have ours run instead as in an "override") these?
I'm assuming the same approach applies to other functions that start with an underscore such as _isAvailable, and _invoke.
The following methods are called for a command:
isAvailable
isEnabled
invoke
The base class for all commands - Tridion.Core.Command - has a standard implementation of these methods. For the most part, this default implementation allows for extensions to Commands. They also call the underscore methods (_isAvailable, _isEnabled, and _execute).
I don't know why the CME commands only overwrite the underscore methods. Maybe someone thought it was just easier that way. They should be consider private (or the equivalent of "protected" in C#), so it actually seems like a bad practice to me.
It would be cleaner to implement the proper methods (isAvailable, isEnabled, and invoke) and then call the base implementation using this.callBase. However, you might need to stop the pipeline in this case, or also overwrite the underscore methods, in order to avoid your return value getting overwritten by the default underscore methods. It depends on the command you are implementing or extending.
In short: using the underscore methods is probably bad practice, but the Core implementation does seem to make it harder for you to do it "right". So I'd aim to avoid the underscore methods, but not sweat it if it turns out to be too hard to do so.
P.S. isValidSelection is a PowerTools-only method which separates the common logic that they all need from the logic specific to each command.
I have the following code
$pageName = "test";
$Container = {};
I like to set a property of $Container by a variable. I tried $Container.set("test", $pageName);. It didn't raise any errors, but $Container.test or $Container.get("test"); display nothing.
How do I fix it?
The problem is that set is the wrong method. You need to do a put. Remember - Velocity is calling the Java methods. There is no "set" method on a Map object.
Specifically, you can do
$Container.put("test", $pageName)
Now, one weird thing is that this will print "true" or "false" in the page, since the Map.put() method returns a boolean. So I always do
#set($dummy = $Container.put("test", $pageName))
which does the put and stores the result in another reference (which you can then ignore) instead of rendering it to the page.
Hey I ran into the same problem is the "true" or "false" printed on the page, and there is a simpler way to handle it. What I did is a little weird, and I did it Confluence, which of course uses Velocity under the covers. I mention that because I understand Velocity can be used in may different applications.
With a Confluence user macro, I check for a previously created attribute on the req variable, the request variable, i.e. "myPageVars". Then I use the put method to put a new key-value pair, based on the macro parameters. By using the $! prefix, rather than just $, the output isn't sent to the screen.
...
$!req.getAttribute("myPageVars").put( $paramKey, $paramValue )
...
I'm somewhat new to Velocity, so I can't guarantee this will work in every context, but it seems syntactically easier than the whole #set ($dummy etc. line.
I have couple of questions about AS3 variables handling by AVM/compiler/scope
.1. This code in Flash will throw an error:
function myFunction() {
var mc:MovieClip=new MovieClip();
var mc:MovieClip=new MovieClip();
}
but it won`t throw an error in Flex (only warning in Editor). Why?
.2. How Flash sees variables in loops? Apparently this:
for (var i:int=0; i<2; i++) {
var mc:MovieClip=new MovieClip();
}
isn`t equal to just: var mc:MovieClip=new MovieClip();
var mc:MovieClip=new MovieClip(); because it will throw an error again as earlier in Flash, but in Flex in function not? Is Flash changing somehow my loop before compilation?
.3. Where in a class in equivalent to timeline in Flash - where in class I would put code which I put normally on timeline (I assume it is not constructor because of what I have written earlier, or maybe it`s a matter of Flash/Flex compiler)?
#fenomas thanks for explaining, but I checked 1. answer and it is not enitirely true :) this code: function myFunction() {
var mc:MovieClip=new MovieClip();
mc.graphics.beginFill(0x0000FF);
mc.graphics.drawRect(0,0,100,100);
mc.graphics.endFill();
addChild(mc);
var mc:MovieClip=new MovieClip();
mc.graphics.beginFill(0x000000);
mc.graphics.drawRect(0,0,30,30);
mc.graphics.endFill();
addChild(mc);
}
myFunction();
will compile in Flash in strict mode but with warning mode turned off and won`t throw an error during compile or runtime.
And it will also compile and execute nicely in Flex (event with -strict -warnings compiler commands) (checked with Flash CS3 and FlashBuilder 4).
The same code, but not wrapped in function will generate compile time error regardless off any error modes turned on (strict/warning)in Flash.
Is that what #back2dos said about Flash Compiler that behaves weirdly?
What is the differences between these two compilers Flash/Flex (why I have to change errors mode in Flash while Flex does not care about anything:) )?
Well, I will explain to you, how package level ActionScript (classes and global functions) is scoping.
The var statement declares a variable within the scope of the function body it is in. It's visibility is within the whole body. thus the following is completely valid.
a = 3;
if (Math.random()>0.5) {
var a:int = 0;
}
else {
a = 6;
}
this is horrible, but it's based on the abandonend ECMA-Script draft AS3 is based on ... yay! :(
for simplicity, imagine that all variable declarations are actually at the start of the containing function body (while their initialisation is actually performed in the place where you put it)
thus
for (var i:int=0; i<2; i++) {
var mc:MovieClip=new MovieClip();
}
is equal to
var i:int, mc:MovieClip;
for (i=0; i<2; i++) {
mc=new MovieClip();
}
the first piece of code from your first question to a duplicate variable defininition, which causes a compiler warning, but works as if you had made only one declaration.
as for your third question: there is no equivalent at all.
AS3 in the flash IDE and many designer friendly concepts (such as frames) are highly ambiguous. from a developer's point of view the flash IDE is about the worst piece of cr*p you can get for money (which stop it from being a great tool for design, drawing and animation). if you want clear and consistent behaviour, I advise you not to use the flash IDE for compiling ActionScript or to waste time on trying to find out why it behaves so weirdly. Apart from its quirks, it takes a long time to compile and the strange things it does to your ActionScript (such as converting local variable declaration to instance field declaration (which is probably the source of your problem)).
These are great questions. In order:
By default, Flash Authoring FLAs start in strict mode. You can change it in File > Publish Settings > AS3 settings. However, duplicate variable definitions are not a runtime error, just something that the authoring environment may or may not throw a warning or error about, depending on configuration and whether it's a class or frame script.
Incidentally, when comparing Flash and Flex make sure that your Flash scripts are inside a class, since frame scripts are a subtle different animal (as discussed below).
AS3 does not have block-level scope, so it implements a practice called "hoisting", where the compiler moves all declarations (but not assignments) to the beginning of the function in which they occur. Hence, even though your var statement is inside a loop, declaration occurs only once when the function begins to execute. See here for more details.
Frame scripts are a bit anomalous. They're sort of like anonymous functions, except that all scripts on a given timeline are considered to be in the same lexical scope. So if you use a var statement to create a local variable in one frame script, the variable will still exist when you execute a different frame script of the same object.
This is basically for historical reasons, but the result is essentially the same as having all your frame scripts in one big function and jumping around with GOTOs. Hence you should always keep all your real code in classes, and use frame scripts only to call class methods that you need to be synchronized with timeline animations. This not only lets you avoid needing to understand precisely how frame scripts differ from class code, it's good coding practice for a couple of reasons unrelated to the stuff we're talking about here.