Jump to content

Finding (the) Closure


Man In Tan
 Share

Recommended Posts

I built a class to imitate closures, while being able to be treated as a regular class, but the syntax needed was ugly, and hard to remember. So now ....I'm building a new class, to make closures more portable. The basic syntax for instantiating one of these objects would be this:

$enclosure = new \us_0gb\enClosure(function($var)use($par){echo $par,$var;});

or

$closure = function($var) use ($par) { echo $par,$var; };$enclosure = new \us_0gb\enClosure($closure);

As you can see, it takes a closure as its argument. Now, I need to isolate the closure's original code.I think it might be impossible if the closure was created using eval(), but I should be able to do it if a hard copy of it exists in the file. Using PHP's built-in ReflectionFunction class, this is what I have so far, with the irrelevant methods removed:

<?php class enClosure {	public function __construct(\Closure $Closure) {		$this->Closure = $Closure;		$ReflectionFunction = new \ReflectionFunction($this->Closure);		$function = \array_slice(file($ReflectionFunction->getFileName()),		($ReflectionFunction->getStartLine() - 1),		($ReflectionFunction->getEndLine() - $ReflectionFunction->getStartLine() ) + 1);		$this->enClosure = \implode("\n", $function);		$begin = \strpos($this->enClosure, 'function');		$end = \strrpos($this->enClosure, '}') - $begin + 1;		$this->enClosure = \substr($this->enClosure, $begin, $end);	}}

However, I'm having issues with nested curly braces:

<?php$par = 'test';$enClosure = new \us_0gb\enClosure(function($var)use($par){echo $par,$var;});echo $enClosure->enClosure,"\n\n";if(!isset($notset)){ $Closure = function($var)use($par){echo $par,$var;}; }$enClosure = new \us_0gb\enClosure($Closure);echo $enClosure->enClosure,"\n\n";

results in:

function($var)use($par){echo $par,$var;}function($var)use($par){echo $par,$var;}; }
Any help would be greatly appreciated.
Link to comment
Share on other sites

It looks like you're trying to achieve the impossible... there's a reason closures were a major "selling point" for PHP 5.3 - they're not doable with previous versions, as in "the syntax for them is invalid for prior versions".If you need compatibility, you can pollute the global namespace with named functions, and use those OR use function_create(). Or are you trying to make a tool to translate closures into a PHP 5.2 compatible syntax? Because THAT is doable.

Link to comment
Share on other sites

Thanks for the fast reply!No, I'm not trying to send the closures to a version prior to 5.3. I'm trying to isolate the closure's code, to save it in a separate file, so it can be reused later, as closures themselves cannot be serialized, and it's kind of bothering me. One of the reasons I even use objects, is their portability. I can save an object from one script, and use it in another, often with a different variable name. Without that capability, I don't really see any advantages to anonymous functions. I may as well just define regular functions.I could even enclose the function in quotes, like so, to be eval()'d later, but then I couldn't capture the current value of $par without some ugly syntax.

new \us_0gb\enClosure('function($var)use($par){echo $par,$var;}');

Link to comment
Share on other sites

Why not rework your closures to named functions? You can easily find them one by one by searching for "function(" (I'm assuming there aren't THAT many used over the code).Closures are supposed to be used "one time", which I guess is the reason they're not directly serializable.

Link to comment
Share on other sites

I'm not sure why it's doing what it's doing, but what about either of these:

if(!isset($notset)){   $Closure = function($var)use($par){echo $par,$var;}; }

if(!isset($notset))  $Closure = function($var)use($par){echo $par,$var;};

I'm trying to isolate the closure's code, to save it in a separate file
What does that mean, are you trying to programmatically create PHP files? I'm not clear on what you're specifically trying to do.
Link to comment
Share on other sites

Why not rework your closures to named functions?
I've been working with only named functions up to now, so I thought it might be fun to try something new. I guess I'm playing around with the closure feature right now, rather than actually building something useful. I should get back to one of my projects that actually serves a purpose, though.
You can easily find them one by one by searching for "function(" (I'm assuming there aren't THAT many used over the code).
I can find the beginning of the closure just fine, it's the end of it I'm having issues with.
Closures are supposed to be used "one time", which I guess is the reason they're not directly serializable.
I suppose you're right. When you put it that way, what I'm trying to do does seem kind of pointless.Thank you for your time and thoughts on the matter. Eventually I'll find a way to build something useful out of this feature, but for now, I'll leave it be.EDIT: I was too slow in forming my response, so justsomeguy's post wasn't visible yet.
I'm not sure why it's doing what it's doing, but what about either of these:
I thought about that, but it'd only work in code I wrote myself. In that case, I may as well use my psudo-closure class.
What does that mean, are you trying to programmatically create PHP files? I'm not clear on what you're specifically trying to do.
Yes, I was creating reusable files from closures in a script. I see that that was pointless, though. Edited by Man In Tan
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...