Custom REPL in nodejs - node.js

I'm trying to play with the nodejs built in REPL from the documentation.
http://nodejs.org/api/repl.html
The example of adding an item is as follows:
repl.start().context.m = msg;
I cant seem to find away to add multiple menus. I've tried doing:
menus = {m = 'hello', f = 'foo'}
repl.start().context = menus
But that doesn't work either. I get:
testREPL> m
TypeError: needs a 'context' argument.
at REPLServer.self.eval (repl.js:113:21)
at Interface.<anonymous> (repl.js:250:12)
at Interface.EventEmitter.emit (events.js:88:17)
at Interface._onLine (readline.js:199:10)
at Interface._normalWrite._line_buffer (readline.js:308:12)
at Array.forEach (native)
at Interface._normalWrite (readline.js:307:11)
at Socket.ondata (readline.js:90:10)
at Socket.EventEmitter.emit (events.js:115:20)
at TCP.onread (net.js:395:14)
Does anybody know how to get this working?

You can't assign to the context property, you have to add properties to it. What you are trying is "overwriting" it with your own object. Try to assign each property by itself instead:
var context = repl.start({}).context;
context.m = 'hello';
context.f = 'foo';

Related

How to get line and file name from Error in Node.js?

Suppose I have:
var err = new Error('My error!');
How to get line and file name, where Error was created?
Like in PHP:
$ex = new \Exception();
$ex->getLine();
$ex->getFile();
To get the file name for the current file: use __filename.
To get the folder for the current file: use __dirname
To parse the file from an Error object, you need an Error with a stack property, that hopefully points to files. You would need then to parse the filename and line from the stack string or use a module that does so.
> new Error().stack
Error
at repl:1:1
at sigintHandlersWrap (vm.js:22:35)
at sigintHandlersWrap (vm.js:73:12)
at ContextifyScript.Script.runInThisContext (vm.js:21:12)
at REPLServer.defaultEval (repl.js:346:29)
at bound (domain.js:280:14)
at REPLServer.runBound [as eval] (domain.js:293:12)
at REPLServer.<anonymous> (repl.js:545:10)
at emitOne (events.js:101:20)
at REPLServer.emit (events.js:188:7)
You can use stack-trace node module. This gives module name and line number

Why _ as variable name in node REPL mode to require failed

Node version v5.4.1 and I installed lodash in current directory's node_modules. And I encouter this issue where '_' seems special.
> var _ = require('lodash');
undefined
> _.defaults
TypeError: Cannot read property 'defaults' of undefined
at repl:1:2
at REPLServer.defaultEval (repl.js:252:27)
at bound (domain.js:287:14)
at REPLServer.runBound [as eval] (domain.js:300:12)
at REPLServer.<anonymous> (repl.js:417:12)
at emitOne (events.js:82:20)
at REPLServer.emit (events.js:169:7)
at REPLServer.Interface._onLine (readline.js:210:10)
at REPLServer.Interface._line (readline.js:549:8)
at REPLServer.Interface._ttyWrite (readline.js:826:14)
> var l = require('lodash');
undefined
> l.defaults
[Function]
>
I saw a question related to undefined output. But no question yet cares about the failure of 'require' when '_' as variable name. Do you know any about it?
The underscore is a special variable that holds the result of the most recent expression. Prior to node v6.0.0, this behavior could not be disabled. However, node v6.0.0 introduced a change that allowed the underscore variable to be overwritten. So you will need to upgrade your copy of node if you want to reassign the _ variable in the node REPL.

Sending bitcoins using bitcoinjs-lib

I'm following tutorial for bitcoinjs at https://medium.com/#orweinberger/how-to-create-a-raw-transaction-using-bitcoinjs-lib-1347a502a3a#.wkf9g2lk0
I receive undefined error for
var key = bitcoin.ECKey.fromWIF("L1Kzcyy88LyckShYdvoLFg1FYpB5ce1JmTYtieHrhkN65GhVoq73");
Reading https://github.com/bitcoinjs/bitcoinjs-lib/issues/487 I use instead
var key = bitcoin.ECPair.fromWIF("L1Kzcyy88LyckShYdvoLFg1FYpB5ce1JmTYtieHrhkN65GhVoq73");
For line : console.log(key.pub.getAddress().toString()); (from tutorial)
I receive similar exception :
TypeError: Cannot read property 'getAddress' of undefined
at repl:1:20
at REPLServer.defaultEval (repl.js:262:27)
at bound (domain.js:287:14)
at REPLServer.runBound [as eval] (domain.js:300:12)
at REPLServer.<anonymous> (repl.js:431:12)
at emitOne (events.js:82:20)
at REPLServer.emit (events.js:169:7)
at REPLServer.Interface._onLine (readline.js:211:10)
at REPLServer.Interface._line (readline.js:550:8)
at REPLServer.Interface._ttyWrite (readline.js:827:14)
'getAddress' method is also deprecated, what to use instead ?
Any other tutorials for sending bitcoins ? They seem difficult to find ?
This should work
var key = bitcoin.ECPair.fromWIF("L1Kzcyy88LyckShYdvoLFg1FYpB5ce1JmTYtieHrhkN65GhVoq73");
var address = key.getAddress().toString()
console.log(address) // 17hFoVScNKVDfDTT6vVhjYwvCu6iDEiXC4
Better still using newer version of bitcoin.js library do
const bitcoin = require('bitcoinjs-lib');
let keyPair = bitcoin.ECPair.makeRandom();
let publicKey = keyPair.publicKey
const { address } = bitcoin.payments.p2pkh({ pubkey: publicKey });
const privateKey = keyPair.toWIF();
console.log(address)
console.log(privateKey)

node.js: Cannot read property 'defaultEncoding' of undefined

I wanted to write a changeable write() function.
var write = function(s) {
process.stdout.write(s);
}
write("Hello world!");
I thought you could just write it shorter:
var write = process.stdout.write;
write("Hello world!");
But here I will receive this error:
TypeError: Cannot read property 'defaultEncoding' of undefined
at Writable.write (_stream_writable.js:172:21)
at Socket.write (net.js:613:40)
at repl:1:2
at REPLServer.self.eval (repl.js:110:21)
at Interface.<anonymous> (repl.js:239:12)
at Interface.EventEmitter.emit (events.js:95:17)
at Interface._onLine (readline.js:202:10)
at Interface._line (readline.js:531:8)
at Interface._ttyWrite (readline.js:760:14)
at ReadStream.onkeypress (readline.js:99:10)
Why is that?
It all has to do with how javascript handles this. Inside the function process.stdout.write there is a call to defaultEncoding() using this variable.
In javascript, this is not assigned a value until an object invokes the function where this is defined and it is relative to the calling object.
So in your first example, this points to process.stdout object and it has the method defaultEncoding.
In your second example, this is undefined since the function is being called from the global namespace. When process.stdout.write tries to call defaultEncoding, it will throw the error you mentioned.
You can manually define the this value for a function using Function.prototype.call() method. Example:
var write = process.stdout.write;
write.call(process.stdout, "Hello world!");
The first argument of call is the object to be used as this inside the function.
I recommend reading this article, it explains a lot about this in javascript.
Use the .bind() method, it is designed exactly for your case.
var write = process.stdout.write.bind(process.stdout);
write("Hello world!");
This sets this variable inside the process.stdout.write method to process.stdout.

custom stream object? (nodejs)

Is it possible to extend / initialize the require('stream').Stream; object ? I would like to be able to create a stream object that i can push data to and have all the listeners notified when new data arrive.
I tried the following:
var stream = require('stream');
var test = new stream.Stream();
test.write(new Buffer('mads'));
But i get the following error:
TypeError: Object [object Object] has no method 'write'
at repl:1:6
at Interface.<anonymous> (repl.js:168:22)
at Interface.emit (events.js:67:17)
at Interface._onLine (readline.js:153:10)
at Interface._line (readline.js:408:8)
at Interface._ttyWrite (readline.js:585:14)
at ReadStream.<anonymous> (readline.js:73:12)
at ReadStream.emit (events.js:88:20)
at ReadStream._emitKey (tty_posix.js:306:10)
at ReadStream.onData (tty_posix.js:69:12)
at ReadStream.emit (events.js:67:17)
For anyone who stumbles on this question today (node v0.10.x), this can be easily achieved using the PassThrough stream introduced with streams2.
var stream = require('stream');
var test = stream.PassThrough();
test.write('mads');
test.end();
You have to create those methods yourself and also set the writable property to true, and don't forget to emit the events in those methods you override as well so that you can use it as a regular event emitter. Check this question for more information.

Resources