On Feb 16, 2013, at 07:48, David Heller wrote:
> Here is the actual php code I'm trying to convert to nodejs:
Sorry for not responding sooner. I've looked at this code a couple times over
the past two weeks and it was somewhat hard to understand given the use of
$GLOBALS and eval(), and also because it's incomplete.
The closing curly brace on line 19 doesn't match anything. I'm guessing that
there were lines omitted at the beginning of this listing that define a
function -- or rather a method, since the use of $this suggests we're in a
class definition.
Not sure what its arguments are, but there are several variables being used
here that I've not seen defined, including $name, $rule, $dat_file, $server and
$port. Sounds like this makes a connection to some server -- or returns an
object for an existing connection. So let's say:
function connect($name, $rule, $dat_file, $server, $port) {
> if(in_array($name, $this->m_names))
> {
> $this->m_rules[$name][] = $rule;
> return $GLOBALS[$name];
> }
m_names is a member of the current object. It's a numerically-indexed array of
strings, where each string is the name of a global variable containing a
GTCM_GNP object. The purpose of the array seems to be to indicate whether an
object has already been created with this name. If the string $name is in the
m_names array, then it is assumed that there is an element $name in the m_rules
array, and that there is a global variable whose name is the contents of the
$name variable. In other words, if $name is the string "foo", then we assume
there is a global variable $foo. The regular expression $rule is appended to
the list of rules for this name in the m_rules array, then the object in the
global variable is returned.
If the name was not in the m_names array, then the object hasn't been created
yet and needs to be created:
> $cmd = "\$$name = new GTCM_GNP(\$dat_file, \$server, \$port);";
> eval($cmd);
This creates a new GTCM_GNP object and assigns it to the variable whose name is
the contents of the $name variable.
I don't see why this trickery with the variable name is being done. According
to the documentation for eval, this should just be creating a local variable
with this name -- a local variable which is returned at the end of this method.
Therefore any arbitrary temporary variable name could have been used.
Furthermore it is completely unclear to me why eval() is being used here. It
doesn't appear to me to be necessary at all or to add anything of value.
But there's no other place in the code you've shown where this variable gets
promoted to a global. So perhaps this code actually makes a global variable,
despite what the documentation says. If so, there's still no need for eval; you
can just assign to $GLOBALS[$name] directly.
In nodejs JavaScript, you wouldn't want to use globals at all; you could just
define a private object in your module and store the objects in there as you
make them.
> if(!$$name)
> {
> $err_msg = "Cannot register, GTCM_GNP constructor failure.";
> catch(throw(__FILE__, __LINE__, "register", 1, $err_msg));
> return FALSE;
> }
If the new variable is empty, meaning the object could not be created, an error
is thrown.
> $this->m_cnt++;
This counter is incremented, presumably a count of how many objects have been
created.
> $this->m_names[] = $name;
The string $name is appended to the m_names array, as an indicator that this
global variable now exists.
> $this->m_rules[$name] = array($rule);
The array of rules for $name is created with a single element: the regular
expression $rule.
> return $$name;
The new object is returned.
> }
It's unclear why $GLOBALS or eval() were needed at all. It seems as though
using a string-indexed array -- as was done for the m_rules array -- would have
worked just as well. In JavaScript, this would be called an object instead of
an array.
> function lookUp($gvn_name)
> {
> foreach($this->m_rules as $name => $rule)
> foreach($rule as $r)
> if(ereg($r, $gvn_name))
> return $name;
> return null;
> }
This looks through all the rules for all the objects, and returns the name of
the object that has a rule matching the $gvn_name variable. This uses the old
deprecated ereg regular expression syntax: http://php.net/ereg ; Use of the
newer PCRE regular expression syntax is recommended in PHP. JavaScript regular
expressions are also PCRE-based.
> /* Usage: $dir->unregister("db1"); */
> function unregister($name)
> {
> if(!in_array($name, $this->m_names))
> return;
> $rule = $this->m_rules[$name];
> $this->m_rules = array_diff($this->m_rules, array($rule));
> $this->m_names = array_diff($this->m_names, array($name));
> $this->m_cnt--;
> }
It looks like this removes all the rules associated with the $name object, and
removes it from the m_names array and decrements the count of objects -- but
does not actually delete the global variable containing the object itself.
So it seems to be a bad / incomplete attempt at object orientation. What you
really want is a single container to hold all your connections. Inside that
container you'd have objects which contain each connection's connection object
and its rules. Here's some code that seems to work, which I saved as
connectionManager.js:
var GTCM_GNP = require('./GTCM_GNP');
var connections = {};
var count = 0;
exports.connect = function (name, rule, dat_file, server, port) {
if (connections[name]) {
connections[name].rules.push(rule);
return connections[name].connection;
}
var newConnection = new GTCM_GNP(dat_file, server, port);
count++;
connections[name] = {
connection: newConnection,
rules: [rule]
};
return newConnection;
};
exports.lookUp = function (gvn_name) {
var names = Object.keys(connections);
for (var i = 0; i < count; i++) {
var name = names[i];
if (connections[name].rules.some(function(rule) {
return rule.test(gvn_name);
})) return name;
}
return null;
};
exports.unregister = function (name) {
if (!connections[name]) return;
delete connections[name];
count--;
};
To test it out I made an index.js like this:
var cm = require('./connectionManager.js');
var conn1 = cm.connect('example', /hello/, 'foo.txt', 'localhost', 5555);
var conn2 = cm.connect('example', /world/, 'foo.txt', 'localhost', 5555);
var conn3 = cm.connect('something', /another/, 'bar.txt', '192.168.99.999',
6666);
console.log(cm.lookUp("I say hello"));
console.log(cm.lookUp("You say goodbye"));
console.log(cm.lookUp('This is another one'));
cm.unregister('example');
console.log(cm.lookUp("I say hello"));
console.log(cm.lookUp("You say goodbye"));
console.log(cm.lookUp('This is another one'));
cm.unregister('something');
console.log(cm.lookUp("I say hello"));
console.log(cm.lookUp("You say goodbye"));
console.log(cm.lookUp('This is another one'));
And a GTCM_GNP.js like this:
function GTCM_GNP(dat_file, server, port) {
this.dat_file = dat_file;
this.server = server;
this.port = port;
console.log('made a new GTCM_GNP object, dat_file ' + dat_file + ', server '
+ server + ', port ' + port);
}
module.exports = GTCM_GNP;
--
--
Job Board: http://jobs.nodejs.org/
Posting guidelines:
https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en
---
You received this message because you are subscribed to the Google Groups
"nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.