After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 584558 - Need print() function
Need print() function
Status: RESOLVED FIXED
Product: gjs
Classification: Bindings
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gjs-maint
gjs-maint
Depends on:
Blocks:
 
 
Reported: 2009-06-01 21:53 UTC by David Zeuthen (not reading bugmail)
Modified: 2009-12-10 17:30 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add print() and printerr() functions (3.76 KB, patch)
2009-06-01 23:09 UTC, David Zeuthen (not reading bugmail)
none Details | Review
Updated patch (4.29 KB, patch)
2009-06-03 18:10 UTC, David Zeuthen (not reading bugmail)
none Details | Review
Bug 584558 – Need print() function (3.81 KB, patch)
2009-12-09 23:19 UTC, Johan (not receiving bugmail) Dahlin
reviewed Details | Review

Description David Zeuthen (not reading bugmail) 2009-06-01 21:53:18 UTC
Seed has a print() function. It would be very useful to have the same in gjs; right now the only way I can get debug output via gjs-console(1) is to use log("foo") and run my program with GJS_DEBUG_OUTPUT=stderr.
Comment 1 Havoc Pennington 2009-06-01 22:22:55 UTC
The complete adjustment discussed earlier was something like:

* log() is changed to be log4j-ish or something, taking a log level or topic
* debug() or trace() output to stderr by default by invoking log()
* print() and printerr() always write to stdout/stderr
* all of the above are "varargs" and concatenate all their args into one string

Maybe useful to get seed input on what the whole API should look like.
Comment 2 David Zeuthen (not reading bugmail) 2009-06-01 23:09:21 UTC
Created attachment 135778 [details] [review]
Add print() and printerr() functions

Here's a patch to add print() and printerr() function. Maybe it would be nicer to use println() but that would give up compat with Seed so not sure it's worth the effort...
Comment 3 Tommi Komulainen 2009-06-02 09:41:25 UTC
Comment on attachment 135778 [details] [review]
Add print() and printerr() functions

It would be really nice if print() and others would accept printf-style format modifiers. Maybe not necessary for the C-function as one could maybe use sprintf js implementation around it, but IMO the global function should be printf-like for convenience.
Comment 4 David Zeuthen (not reading bugmail) 2009-06-03 18:10:52 UTC
Created attachment 135898 [details] [review]
Updated patch

Updated function that concatenates arguments; here's an example of how to use it

#!/usr/bin/env gjs-console

const Gio = imports.gi.Gio;

let icon = new Gio.ThemedIcon ({name : "drive-cdrom-writer", use_default_fallbacks : true});

// this prints out the following line
//
// Hello world foobar 42 '. GThemedIcon drive-cdrom-writer drive-cdrom drive' 8
//
print ("Hello world" + " foobar ", 42, " '", icon.to_string (), "' ", Gio.FileCopyFlags.ALL_METADATA);
Comment 5 David Zeuthen (not reading bugmail) 2009-06-03 18:12:33 UTC
(In reply to comment #3)
> (From update of attachment 135778 [details] [review] [edit])
> It would be really nice if print() and others would accept printf-style format
> modifiers. Maybe not necessary for the C-function as one could maybe use
> sprintf js implementation around it, but IMO the global function should be
> printf-like for convenience.

Wouldn't you rather use GLib.print() for that? I don't know.

Comment 6 David Zeuthen (not reading bugmail) 2009-06-03 18:41:41 UTC
Also, any thoughts about newline? I think it's a bit broken that we append the newline automatically, it's typically not what you want, e.g. sometimes you want to be able to do things like this

 print ("foo ")
 if (frob.should_do_bar ()) {
   print ("bar");
 } else {
   print ("baz");
 }
 print ("\n");

although I suppose that could be done through just building a string. I don't know.
Comment 7 Havoc Pennington 2009-06-03 19:16:43 UTC
could have println() that tacks on newline and print() that does not maybe.

log() I believe appends newline only if there isn't one already, which is sort of convenient for a true debug log function.

I wouldn't mind just a half-page quick spec for the whole plan around printing and logging, maybe my bullet points above are good enough, and be sure everyone who cares has a chance to comment.

Comment 8 Owen Taylor 2009-08-24 18:06:00 UTC
Hmm:

 print ("Hello world" + " foobar ", 42, " '", icon.to_string (), "' ",
Gio.FileCopyFlags.ALL_METADATA);

Doesn't delight. I think either:
 
 - You want to do somethin sophisticated like the above, and for that
   you really want string formatting of some type

 - You want to do a quick:

     print (x, y);

    Debug print, and for that, having to write:

     print (x, ",", y);

    To avoid an unparsable 12345 always makes me want to cry. 

So, I'd be in favor of adding spaces between arguments, along the lines of:

 http://docs.python.org/reference/simple_stmts.html#the-print-statement

String formatting seems best to me done at the JS level and operating on strings, rather than built into print/log - sprintf() not printf().

[ Though the advantage of building formatting into log() is efficency when not logging, as always ] 

But there are numerous questions there: e.g. you go with {0} in the style of log4j, C#, and python 3, or do you go with %s in the style of C, Java's formatter, python 2, etc. What's the API look like? etc.

A couple of comments on the patch:

 1) The duplicated code between gjs_print and gjs_printerr is ugly, they could easily be written in terms of a common function, it seems.

 2) 

+        } else {
+            gjs_debug(GJS_DEBUG_LOG, "<cannot convert argument %d to string>", n);
+            g_string_free (str, TRUE);
+            return JS_TRUE;
+        }

I cant' believe that the right behavior for hitting an exception is to debug and print nothing and not throw an error (especally since gjs_debug() goes to /dev/null by default now.)
Comment 9 C. Scott Ananian 2009-09-14 18:04:43 UTC
FWIW, my vote's with print() and println() and space-separating the arguments.  It's javascript, you can always do:

 print = imports.gi.GLib.print

if you want something different.

For true logging, you probably want the option to pass a function to the logger, so that you don't pay for formatting when you're not logging.  Something like:

 log("Unexpected input:", function() { return obj.toString(); })

or, in JavaScript 1.8 syntax:

  log("Unexpected input:", function() obj.toString());
Comment 10 Luis Medinas 2009-09-16 16:35:38 UTC
Someone has tested GLib.print ? It does appear to work.
Comment 11 Havoc Pennington 2009-09-16 16:38:45 UTC
GLib.print might work with no args, but something like this will not:

GLib.print("%d %d %d %d", 1, 2, 3, 4)

h
Comment 12 Luis Medinas 2009-09-17 02:12:03 UTC
Ok, testing

const GLib = imports.gi.GLib;

GLib.print("test");


gjs testeprint.js 
    JS ERROR: !!!   Exception was: Error: No symbol 'print' in namespace 'GLib'
    JS ERROR: !!!     lineNumber = '0'
    JS ERROR: !!!     fileName = 'gjs_throw'
    JS ERROR: !!!     stack = 'Error("No symbol 'print' in namespace 'GLib'")@:0
("No symbol 'print' in namespace 'GLib'")@gjs_throw:0
@testeprint.js:3
'
    JS ERROR: !!!     message = 'No symbol 'print' in namespace 'GLib''


Besides a print function something like readline/scanf would be useful too.
Comment 13 Johan (not receiving bugmail) Dahlin 2009-12-09 23:19:50 UTC
Created attachment 149492 [details] [review]
Bug 584558 – Need print() function

Updated patch, this changes:
- Reduces the duplication between print/printerr
- Adds a space between the arguments
- Always adds a newline

For the space between the arguments discussion, yes
it's the right thing to do and if you want another
behavior you can easily write your own string formatting
function on top and send it out.

For the newline discussion. You almost always want to
add a space in the end, it's most certainly the best thing
to do. For other use cases, build a string and send it to
print.

We shouldn't let this get bike shredded by the formatting
discussion, which is a separate bug. We have a sprintf
javascript implementation in litl which we should probably
open source for that.
Comment 14 Colin Walters 2009-12-10 15:36:08 UTC
Review of attachment 149492 [details] [review]:

Big picture...this is OK, but I'd like to have https://bugzilla.gnome.org/show_bug.cgi?id=588828 too.

::: gjs/context.c
@@ +183,3 @@
+                     uintN      argc,
+gjs_print_parse_args(JSContext *context,
+static JSBool

NULL sets the string up to be binary; I'd use "" here.

@@ +194,3 @@
+        jstr = JS_ValueToString(context, argv[n]);
+        if (jstr != NULL)
+            argv[n] = STRING_TO_JSVAL(jstr); // GC root

Hmm...how does that work?  Is the whole argv array guaranteed to be rooted?

Now there is a hack in spidermonkey where one new object of each type (e.g. String) is automatically rooted, but here we're creating many strings.

Anyways it'd feel cleaner to me if we used JS_EnterLocalRootScope
then JS_LeaveLocalRootScope.
Comment 15 Johan (not receiving bugmail) Dahlin 2009-12-10 17:30:54 UTC
I addressed the Colin mentioned and pushed this, thanks!