Anonymous function works as callback but defined function does not - coffeescript

I have a module that looks like this:
module.exports = AtomMarkdownLabels =
# other stuff here
file_changed_added: (file_path) =>
fs.readFile file_path, 'utf-8', #process_yaml
console.log 'file changed'
process_yaml: (err, data) =>
console.log "process_yaml is called"
I know file_changed_added is being called from some other function and I'm seeing the "file changed" output in the console, but process_yaml isn't if I change file_changed_added to
file_changed_added: (file_path) =>
fs.readFile file_path, 'utf-8', (err, data) =>
console.log "test"
console.log 'file changed'
I see both "test" and "file changed" being called properly. What could be going on?

=> has two slightly different purposes:
When defining a named function (f = => ...) or anonymous function f(x, => ...)), => simply ensures that # inside the function is that same as # in the surrounding context.
When defining a method in a class:
class C
m: => ...
=> ensures that # inside m will be the instance of C.
Both uses are creating a bound function but they're binding to different things.
You're using this structure:
obj =
func: =>
# ...
That's equivalent to this:
f = =>
# ...
obj =
func: f
because you're using a plain old object rather than a class. So what is # outside your AtomMarkdownLabels definition? # won't be anything useful and in particular, it won't be your AtomMarkdownLabels object and it won't have a process_yaml property so #process_yaml inside file_changed_added is going to be undefined or an error.
I'm not sure what specifically Atom wants you to return but a class should work, something like this:
# Use a class so that => does what you're expecting it to do
class AtomMarkdownLabels
# other stuff here
file_changed_added: (file_path) =>
fs.readFile file_path, 'utf-8', #process_yaml
console.log 'file changed'
# you may or may not need => here
process_yaml: (err, data) =>
console.log "process_yaml is called"
# Export an instance of your class
module.exports = new AtomMarkdownLabels
If you want to or must use a plain object then you could bypass # completely and do it like this:
# Just plain old functions so define them that way
process_yaml = (err, data) ->
console.log "process_yaml is called"
file_changed_added = (file_path) ->
fs.readFile file_path, 'utf-8', process_yaml
console.log 'file changed'
module.exports = AtomMarkdownLabels =
# other stuff here
file_changed_added: file_changed_added
or like this:
# Explicitly name your object rather than using #
module.exports = AtomMarkdownLabels =
# other stuff here
file_changed_added: (file_path) ->
fs.readFile file_path, 'utf-8', AtomMarkdownLabels.process_yaml
console.log 'file changed'
process_yaml: (err, data) ->
console.log "process_yaml is called"
This should solve your other CoffeeScript problem from a few days ago too.

Related

How to use aggregations framework in new Elasticsearch using Perl language

I am working on Elasticsearch and I have to do aggregations (i.e used for summarize our data) I shared my code below....
CODE:
my $portal_es = Search::Elasticsearch->new(nodes => [$es_ip.':'.$es_port],request_timeout => 180);
my $result = $portal_es->scroll_helper(index => 10002500,size =>"10000", params=>{rest_total_hits_as_int =>true},{
#"size": 0,
aggs=> {
"my-agg-name"=> {
terms=> {
field=> "tcode"
}
}
}
});
I am getting following error
[Param] ** Expecting a HASH ref or a list of key-value pairs, called from sub Search::Elasticsearch::Role::Client::Direct::Main::scroll_helper at /home/prity/Desktop/BL_script/search_index_processor/aggregation.pl line 15. With vars: {'params' => ['index','10002500','size','10000','params',{'rest_total_hits_as_int' => 'true'},{'aggs' => {'my-agg-name' => {'terms' => {'field' => 'tcode'}}}}]}
The data structure in your argument list is probably broken.
my $result = $portal_es->scroll_helper(
index => 10002500,
size => "10000",
params => {
rest_total_hits_as_int => 'true'
},
{ # <---- here
aggs => {
# ...
You are passing a list of key/value pairs into the scroll_helper, but there is one extra last argument after params. It's a hash reference with aggs in it that has no key for it.
Turn on use warnings and you'll get a warning that your data structure is missing a value (because that hashref will stringify into a key).
You probably shouldn't have closed the hashref for params and opened a new one. But that's just a guess, I don't know what this method expects.

Puppet - deep merge lookup default_value with hiera hash returned

I am trying to deep merge the lookup 'default_value' or 'default_values_hash' with the hash returned from a lookup. It will not merge and the default_value only appear to take effect if the hiera title isn't found at all. I cannot set resource defaults here as the values returned are later processed and not actual resource keys yet.
I've tried numerous variations including 'default_value', 'default_values_hash'. I'm seeking a way to just set a default hash in the manifest and have it deep merge with hiera to create a larger hash.
Manifest:
class test (
Hash $result = lookup('test::my_hash', {merge => 'deep', default_values_hash => {foo => 'bar', this => 'that', him => 'her'}}),
){
notice($result)
}
include test
Hiera:
---
test::my_hash:
foo: 'nobar'
this: 'then'
desired result (deep merge):
{ foo => 'nobar', this => 'then', him => 'her' }
actual result (returns hiera hash only):
{ foo => 'nobar', this => 'then' }
UPDATE:
I got it working with the code below. Still interested if anyone has a better solution.
class test (
$stuff = {
foo => 'bar',
this => 'that',
him => 'her'
},
Hash $result = deep_merge($stuff, lookup('test::my_hash')),
){
notice($result)
}
Unfortunately, that is the way lookup works. The default value is only used if no other value is found. The documentation for the default in lookup says
If present, lookup returns this when it can’t find a normal value. Default values are never merged with found values.
Your version using the deep_merge function from stdlib appears to be the best solution.
class foo {
$default_foo_attribute = {
foo => 'bar',
this => 'that',
him => 'her',
}
$attribute = deep_merge($default_foo_attribute,
lookup('foo::attribute',
Hash[String, String],
'deep',
{})
notice($attribute)
}

Perl: How to get the value of an attribute of an object

In the below example, how would i print out the thread id?
$r_event = {
'type' => 'READ_' . $task . '_STARTED',
'timestamp' => $timestamp,
'threadid' => $threadId,
'fdn' => $fdn
};
You have a hash reference there (and those are often used as objects and that's what JSON calls an "object"). You can use the -> to dereference it and put the key you want in curlies:
print $r_event->{'threaded'};
This is just like a normal hash. Note the % and the parens instead of curlies:
%r_event = (
'type' => 'READ_' . $task . '_STARTED',
'timestamp' => $timestamp,
'threadid' => $threadId,
'fdn' => $fdn
);
In that case it's just $r_event{'threaded'} with no arrow since there's no reference.
My book Intermediate Perl covers this and you'll also find it in perlref.

phpseclib createKey() using own primes

Is it possible to generate private and public key in PKCS#1 format using phpseclib and my own primes? I mean I already have p and q and I want to generate both keys. I am trying to do something like this:
$p = new Math_BigInteger(...);
$q = new Math_BigInteger(...);
$custom_primes = serialize(array('primes'=>array(1=>$p,2=>$q)));
extract($rsa->createKey(512,10,$custom_primes));
But this gives me the fatal error:
Fatal error: Call to a member function divide() on a non-object in /volume1/web/phpseclib/Crypt/RSA.php on line 705
I checked this and it is trying to divide:
list($temp) = $lcm['top']->divide($lcm['bottom']);
Obviously I am not setting up lcm in my $custom_primes structure as I only have my two primes. So the question is: is it possible at all in phpseclib?
It looks like you're trying to use phpseclib's partial key functionality to achieve this. Problem is that expects more than just primes. See this, for example:
return array(
'privatekey' => '',
'publickey' => '',
'partialkey' => serialize(array(
'primes' => $primes,
'coefficients' => $coefficients,
'lcm' => $lcm,
'exponents' => $exponents
))
);
$lcm is defined, initially, like this:
$lcm = array(
'top' => $this->one->copy(),
'bottom' => false
);
So maybe try doing that as well. You can probably strip out all of the calculation functions
from phpseclib, do them yourself and then pass $partial into phpseclib and let it generate a key in whatever format you want it generated in.

Is it possible to conditionally pass options to a method in perl?

Similar to this question regarding Ruby, I'd like to conditionally pass parameters to a method. Currently, I have it configured as follows:
my $recs = $harvester->listAllRecords(
metadataPrefix => 'marc21',
metadataHandler => 'MARC::File::SAX',
set => 'pd',
from => $from,
until => $until,
);
What I'd like is to be able to conditionally pass the from and/or until parameters, depending on previous code. This is not syntactically correct, but something like this:
from => $from if ($from),
until => $until if ($until),
or this:
if ($from) {from => $from,}
if ($until) {until => $until,}
Is this possible, and if so, how would I go about doing it?
You could use the ternary ?: operator with list operands:
my $recs = $harvester->listAllRecords(
metadataPrefix => 'marc21',
metadataHandler => 'MARC::File::SAX',
set => 'pd',
$from ? (from => $from) : (),
$until ? (until => $until) : (),
);
It may also be worth knowing about the "conditional list include" pseudo-operator, which in this case would work like
...
(from => $from) x !!$from,
(until => $until) x !!defined($until),
...
but the ternary operator expression is probably easier to read for most people.
The other option is to build a list (or hash) of args and then call the method:
my %args = (
metadataPrefix => 'marc21',
metadataHandler => 'MARC::File::SAX',
set => 'pd',
);
$args{from} = $from if $from;
$args{until} = $until if $until;
my $recs = $harvester->listAllRecords(%args);