My Script is storing a ClearCase View in a Variable. To operate in this View, the Script needs to call itself inside the View again, after it started the View.
The Code looks like this
if($params{ViewSet} eq 'no')
{
# Start the View
# Store the View in $View
# Call the Script in the new-set View with parameter -ViewSet yes
}
if($params{ViewSet} eq 'yes')
{
# Do Work inside the View
}
The problem is, obviously the Variable $View is not defined when I call my script the second time, since it is defined in the first if loop.
Can I pass the View I stored in $View when I call the Script the second time?
Setting the View before entering the if-Statements would not word, I would start the View two times then.
Call the Script in the new-set View with parameter -ViewSet
If that involve calling cleartool setview, don't: setview spawns a subshell in which what you have defined in your script won't be visible.
When your script needs to access the dynamic view started, do use the full dynamic view path:
/view/myDynView
# under which you would see:
/view/myDynView/vobs/MyVob
Related
I am creating a PowerShell GUI that uses a link label. My code for this link is
$ExLinkLabel = New-Object System.Windows.Forms.LinkLabel
$ExLinkLabel.Location = New-Object System.Drawing.Size(15,130)
$ExLinkLabel.Size = New-Object System.Drawing.Size(150,20)
$ExLinkLabel.LinkColor = "BLUE"
$ExLinkLabel.ActiveLinkColor = "RED"
$ExLinkLabel.Text = "Link Example"
$ExLinkLabel.add_Click({[system.Diagnostics.Process]::start("https://google.com")})
$Form.Controls.Add($ExLinkLabel)
Now say I want to change it another website later in the code based on certain conditions, I tried doing this:
$ExLinkLabel.add_Click({[system.Diagnostics.Process]::start("https://yahoo.com")})
The problem that this now has two links open, both google and then yahoo.
Is there a way to clear or just replace that first link with my new one?
Thank you
Adding an event handler with an .add_<EventName>() method call does just that: It adds an additional event handler, of which there can be many.
In order to replace an event handler, you must first remove its old incarnation with .remove_<EventName>(), and then add the new incarnation with .add_<EventName>().
To that end, you must store the original incarnation in a variable that you can later pass to the .remove_EventName>() call:
# Define the original event handler, store it in a variable,
# and add it to the control.
$currEventHandler = { Start-Process https://google.com }
$ExLinkLabel.add_Click($currEventHandler)
# ...
# Remove the current event handler...
$ExLinkLabel.remove_Click($currEventHandler)
# ... and add the new one:
$currEventHandler = { Start-Process https://yahoo.com }
$ExLinkLabel.add_Click($currEventHandler)
Note that I've replaced [system.Diagnostics.Process]::start($url) with a simpler, PowerShell-idiomatic call to the Start-Process cmdlet.
In your simple case, where the two event handlers only differ by the URL they open, consider the alternative recommended by Theo:
Retain the original event handler and make it retrieve the URL to open from a variable defined outside the event handler, namely in the script scope. That way, all you need to do is to update the variable.
# Set the original URL
$url = 'https://google.com'
# Due to PowerShell's dynamic scoping, the event-handler script
# block - even though it runs in a *child* scope - sees the
# script scope's definition of variable $url
# You can make this cross-scope access explicit by using $script:url
# (If you wanted to *update* the variable from inside the child
# scope $script:url *must* be used.)
$ExLinkLabel.add_Click({ Start-Process $url })
# ...
# Update the variable, after which the event handler will
# use the new URL.
$url = 'https://yahoo.com'
This is another of those utilities where every blogger\tutor assumes we all know what it is, therefore they never bother to explain what it actually does. They just go on to use it in their examples, believing we all know what's going on.
From how people use or refer to render(), it would suggest that it displays content(eg: view content) but if this is so, then why do we use echo to actually display it's content?
Other uses suggests that it formats content, as used in form-decorators where internally we employ sprintf() to inject variables into strings.
So what does render() do in cases like Zend_View, Zend_Layout, etc? Can someone please explain it's workings on a fundamental level(under the hood). Thanks.
It loads a view script and outputs it as a string.
Simplifying a bit, Zend_View takes a view script file (like index.phtml) and includes it internally to produce the HTML output. By using the render() method, it's possible to take an additional view script (like maybe nav.phtml) and output it inside your parent view script. The idea is to render elements that are repeated on many pages just one single time instead of repeating the same HTML over and over again.
The code for the render method can be found in the Zend_View_Abstract class and is the following:
/**
* Processes a view script and returns the output.
*
* #param string $name The script name to process.
* #return string The script output.
*/
public function render($name)
{
// find the script file name using the parent private method
$this->_file = $this->_script($name);
unset($name); // remove $name from local scope
ob_start();
$this->_run($this->_file);
return $this->_filter(ob_get_clean()); // filter output
}
The implementation of the _run() method can be found in the class Zend_View and is the following:
/**
* Includes the view script in a scope with only public $this variables.
*
* #param string The view script to execute.
*/
protected function _run()
{
if ($this->_useViewStream && $this->useStreamWrapper()) {
include 'zend.view://' . func_get_arg(0);
} else {
include func_get_arg(0);
}
}
As you can see, render() takes a view script name, resolves its file name, initiates output buffering, includes the view script file (this is what the _run() method does internally), then passes the output through optional filters and finally returns the generated string.
The neat thing about it is that it retains the properties (variables) of the view object it is called from (because it's the same Zend_View object, just with a different view script loaded). In this respect, it differs from the partial() method, which has its own variable scope and you can pass variables into it (making it useful for rendering smaller elements, such as single rows of data when you foreach over a dataset).
I have a function that includes another scripts:
function include-function($fileName)
{
.$fileName
}
I store this function in another script
From my main script I want to first include this script and then include another script:
."c:\1.ps1" #include first file
include-function "c:\2.ps1" #call function to include other functions
xtest "bbb" #function from 2.ps1 that should be included
The problem is that function xtest from 2.ps1 is not visible in main script, it's only visible in scope of include-function. Is there a way to pass xtest to main script?
My include function doesn't realy load file (it gets it as string from API), so I can't call it directly from main script. As a workaround I just changed include-function to return me contents of a file and then from main script I call Invoke-Expression (include-function "c:\2.ps1")
Thanks
The explanation is the scope of your vars and function if in 2.ps1, you declare your vars and functions as globals they will be visible in the global scope.
Exemple of 2.ps1 :
$global:Var2="Coucou"
function global:Test2 ([string]$Param)
{
write-host $Param $Param
}
usage test.ps1:
function include-function($fileName)
{
.$fileName
}
Clear-Host
include-function "c:\silogix\2.ps1"
Test2 "Hello"
gives :
Hello Hello
As you tag your question in PowerShell V2.0 you'd better have a look to modules. using module will end in a best structured programmation see about_Modules.
i have a problem with calling a function which name is a string.
I made few helpers which i want to echo in my phtml file like this:
echo $this->EditProfile();
echo $this->ViewProfile();
The EditProfile() and ViewProfile() are names of the View Helpers which i created and i'm calling them in view. And this method is working fine. But when i want dynamicly call a function by name stored in database im trying to do this in this way:
im getting the names of helpers from database and store them into array and then trying to display them in foreach.
foreach ($this->modules as $key => $module)
{
echo $this->$module['name'];
}
the variable
$module['name']
contains a valid name of Helper which i want to call in phtml file (checked with Zend_debug::dump() and with just an echo $module['name'] in foeach and id display it properly... but this echo its not working and not calling the View Helper, nothing is displayed
when i try eval or call_user_func too nothing is displayed too... How can i do this in foreach or other loop?
ok solved it myself :)
dont know is this solution properly but its actually working ;)
instead call_user_func i mentioned that magical function __call is same as call_user_func_array
so i edited code like this below
foreach ($this->modules as $key => $module)
{
$this->__call($module['name'],array(null));
}
in this case array is null cause none parameters are passed to function. If in my helper ill need parameters ill pass them in this array in future.
And this solution works fine for me :)
If someone have better solution please post it here and share your opinion ;)
regards
Darek
I'm implementing Powershell PSProvider for some internal hierarchical data. Everything works fine, I can navigate through the tree with usual cd/dir commands, the only thing doesn't work is tab completion.
What I can see is that Powershell calls function GetChildName() with an asterisk in the path when Tab is pressed (if I type "dir c" and press Tab, GetChildName() function will be called with string "c*", several times). I tried to return all child names from the folder that begins with "c", but Powershell always displays just the first child name in the front. I can't find any documentation about this behavior, what I'm missing?
Are you sure you aren't just seeing normal behavior? With the default Tab Expansion, you will only see the first result. Pressing tab additional times will cycle through the list of returned results from the provider.
There are some quirks with providers. I have been working on one using the Script Provider project. I put debug code in all my methods to see which ones PowerShell was calling, when, and with what arguments.
I found where's the problem - function GetChildName() in the provider shouldn't try to expand given file name if asterisk is part of the name; The function should return child name if it can find an exact match, or call base.GetChildName() in any other case. Something like this:
protected override string GetChildName(string path) {
string name = SomeFunctionThatTriesToFindExactMatchForGivenPath(path);
if(string.IsNullOrEmpty( ret ) )
ret = base.GetChildName( path );
return ret;
}
BTW, I found that default tab expansion is very forgiving about stuff that can be returned from GetChildName() function - even if return value have slash/backslash in the front/back, tab expansion will work. But PowerTab, popular tab expansion module, is much more picky about return values.