Skip to content

Instantly share code, notes, and snippets.

@mmalecki
Created June 27, 2012 00:09
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmalecki/3000364 to your computer and use it in GitHub Desktop.
Save mmalecki/3000364 to your computer and use it in GitHub Desktop.
function getLine(offset) {
var stack = new Error().stack.split('\n'),
line = stack[(offset || 1) + 1].split(':');
return parseInt(line[line.length - 2], 10);
}
global.__defineGetter__('__LINE__', function () {
return getLine(2);
});
console.log(__LINE__);
console.log(getLine());
@jfhbrook
Copy link

I didn't think defining getters on the global object like that would work.

@mmalecki
Copy link
Author

It actually does. Give it a try.

@aheckmann
Copy link

@jcubic
Copy link

jcubic commented Jun 27, 2012

Where can I run this code?

on Rhino I get this:
js: uncaught JavaScript runtime exception: ReferenceError: "__LINE__" is not defined.

and in node I get:

undefined:1

^
ReferenceError: __LINE__ is not defined
    at Object.<anonymous> (eval at <anonymous> (eval:1:82))
    at Object.<anonymous> (eval:1:70)
    at Module._compile (module.js:441:26)
    at startup (node.js:80:27)
    at node.js:555:3

version:

   { node: '0.6.15',
        v8: '3.6.6.24',
        ares: '1.7.5-DEV',
        uv: '0.6',
        openssl: '0.9.8o' }

in Google Chrome I get:
Uncaught ReferenceError: global is not defined

@jfhbrook
Copy link

@jcubic node.js

@jcubic
Copy link

jcubic commented Jun 27, 2012

It's working, I run node -e __LINE__.js instead of node __LINE__.js. I wish this could run in the browser __defineGetter__ is pretty awesome.

@shinuza
Copy link

shinuza commented Mar 1, 2013

@jcubic This does work in the browser (use window instead of global), apparently IE10 added support for Error#stack. You also would rather use Object.defineProperty as MDN marks defineGetter as deprecated.

@QaidYann
Copy link

With "window" :
...
window.defineGetter('LINE', function () {return getLine(2);});
alert(LINE);

For those who have lost...

window.defineGetter('LINE',function(){
var e=new Error()
,s=(e.stack||'').split('\n')
,l=s[1]||''
,b=navigator.userAgent;
if(b.match(/chrome/gi)){l=(s[2]||'');}
return l.split(':')[2]||false;
});

@gdanen
Copy link

gdanen commented Oct 2, 2015

It finally worked for me like this (using Chrome 45 under Windows 7):

function getLine(offset) {
    var stack = new Error().stack.split('\n'),
        line = stack[(offset || 1) + 1].split(':');
    return parseInt(line[line.length - 2], 10);
}
window.__defineGetter__('__LINE__', function () {
    return getLine(2);
});

console.log('sample.js @ ' + __LINE__ );

@l3laze
Copy link

l3laze commented Jan 7, 2018

Modified this to

function getLine (err) {
  let stack = err.stack.split('\n')
  let line = stack[1 + 1].split(':')
  return parseInt(line[line.length - 2], 10)
}

And now I can pass in an error object after catching it and before re-throwing to preserve the line where it occurred, where I would normally get the line that I re-throw the error at in Node.JS. A bit more complex than the below, but this seems like a good example:

let val
try {
  Object.assign(val, 1)
} catch (err) {
  let reason = `${err.message.toLowerCase()} ("${err.code || err.name || 'error'}" @ line ${getLine(err)})`
  throw new Error(`Failed to do something because: ${reason}.`)
}

Of course this requires looking at the error message, but that's what logging is for, and I think it will make [my] life a little easier by helping to find some bugs that get past the standard-js linter like the above example.

Thank you :D

Edits: eventually fixed formatting. I really hate MD sometimes. https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet helped.

Another edit: That's also without assigning it to global or window; just using it as a private function in a module without that part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment