Hopbot log for 2007-07-18 - Helma IRC channel: #helma on irc.freenode.net

2007-07-18:

[10:40] <midnightmonster> tech, read your rails/helma comparison. was going to reply, but couldn't think of anything useful to add--all seemed fair to me.
[12:00] <zumbrunn> which rails/helma comparison?
[12:03] <zumbrunn> this? http://technomancy.us/85/
[12:40] <treenyc> hi
[12:41] <treenyc> I'm having an issue with helma.File writing to file system
[12:41] <zumbrunn> Hi treenyc!
[12:41] <treenyc> hey chris
[12:41] <treenyc> here is my code
[12:41] <treenyc> var path = '/tmp/helma.txt';
[12:41] <treenyc> res.writeln(path);
[12:41] <treenyc> var t = new helma.File(path);
[12:41] <treenyc> t.open();
[12:41] <treenyc> var date = new Date();
[12:41] <treenyc> res.writeln("canwrite: " +t.canWrite());
[12:41] <treenyc> var str = date.toString();
[12:41] <treenyc> res.writeln(str);
[12:41] <treenyc> res.writeln(t.lastError);
[12:41] <treenyc> t.writeln(str);
[12:41] <treenyc> t.flush();
[12:41] <treenyc> t.close();
[12:42] <treenyc> it writes to the file the first time
[12:42] <treenyc> but then once the file exists it no longer make modification to the file
[12:42] <treenyc> so the file always look like "Wed Jul 18 2007 05:51:08 GMT-0400 (EDT)"
[12:44] <zumbrunn> t.flush() should clear the file
[12:44] <zumbrunn> so you shouldn't even have that date in there
[12:44] <zumbrunn> am I reading the code wrong?
[12:44] <treenyc> ok, I have also tried it without the t.flush()
[12:45] <treenyc> and the file just stay the same
[12:45] <treenyc> sorry, I was trying a few different thing. wasn't sure what I was doing wrong
[12:46] <treenyc> I took out t.flush()
[12:46] <treenyc> I'm using the 1.6 btw
[12:46] <treenyc> so the first time the script is hit, it will create the file /tmp/helma.txt
[12:46] <treenyc> with the date Wed Jul 18 2007 08:47:41 GMT-0400 (EDT)
[12:47] <treenyc> all subsequent hit doesn't change the file at all
[12:49] <zumbrunn> hmm, same thing for me
[12:49] <treenyc> is that expected behavior? or a bug?
[12:50] <zumbrunn> It's certainly not what I'm expecting
[12:51] <treenyc> so I can add t.remove();
[12:51] <treenyc> before the t.open();
[12:51] <treenyc> but shouldn't it have something in write that append to the file or truncate the file
[12:57] <zumbrunn> I just tested it with a older Helma version and it behaves the same
[12:57] <zumbrunn> but I am surprised
[13:06] <treenyc> yeah I tested with 1.5.3 too
[13:07] <treenyc> I just want make sure I'm not missing something, like calling a method before i write
[13:17] <treenyc> another question
[13:17] <treenyc> app.addCronJob("exportIndexNumber", "*", "*", "*", "*", "*", "0-59");
[13:19] <treenyc> this should run cronJob every minute right?
[13:19] <treenyc> does it matter where the cronJob is added ? does it need to be in the Global dir?
[13:21] <zumbrunn> no, it doesn't need to be in the global dir
[13:22] <zumbrunn> yes, that would be every minute, but that's the default anyway
[13:22] <zumbrunn> so you could just pass the function name
[13:24] <treenyc> ok then I don't think it is working
[13:24] <treenyc> app.addCronJob("exportIndexNumber", "*", "*", "*", "*", "*", "0-59");
[13:24] <treenyc> this is inside Root
[13:24] <treenyc> but it not running every minute
[13:24] <treenyc> I have restarted server
[13:36] <treenyc> ok nevermind. My mistake
[13:45] <zumbrunn> what was the problem?
[16:50] <midnightmonster> zum, yes, that Rails/Helma comparison
[16:50] <zumbrunn> I hadn't seen it before
[16:51] <zumbrunn> technomancy was probably working on the site when I was trying to follow a link to it recently ;-)
[16:51] <midnightmonster> me neither. I assumed it was new, but I see it's a month old. Helma stuff is getting pushed up on programming.reddit.com lately, which I think is where I got the link
[16:59] <midnightmonster> oh, re: the anagrams script that won't die, on my server the PHP version runs in only 0.6 sec, so even though Helma's faster on my server, it's not as much faster as the PHP is and it's back to 100% slower. That's not really a complaint, though--it's just a puzzle, not something I'll ever have to do in a production app.
[16:59] <midnightmonster> (100% slower [than the PHP version])
[17:21] <midnightmonster> Chris (probably I should call you that instead of zum), if I wanted to store a moderately large chunk of binary data, e.g., an mp3, with each of a set of HopObjects using the native db, what's the best way to do that? I'm assuming just leaving the data in a property would have unpleasant memory/performance effects.
[17:22] <midnightmonster> also, does the db store properties that aren't specified in the type.properties file?
[17:24] <midnightmonster> ok, this is my thought on how to implement:
[17:28] <midnightmonster> write an onPersist method that saves the mp3 to a file instead and an action to retrieve the file itself, which could be done with, e.g., res.forward if I store the files in the protectedStatic directory. looking at the reference, though, I'm missing a seemingly essential 'onRemove' method--how do I ensure the file gets deleted if the HopObject does?
[17:29] <midnightmonster> I could do this.deleteHopObject = this.delete; this.delete = function(){ /* remove mp3 */; this.deleteHopObject(); }, but that's a little hackish
[17:32] <midnightmonster> and there's a small package that adds aspect-oriented features to Helma, which would just be a less ugly way of doing the same thing, but there's a warning in there about needing some particular method implemented in order for the aspect changes to persist, but I can't find the page any more and didn't understand what that method had to do
[18:07] <zumbrunn> midnightmonster, you are probably thinking about onCodeUpdate()
[18:07] <zumbrunn> http://helma.zumbrunn.net/reference/global.html#onCodeUpdate
[18:08] <zumbrunn> reagarding the storing of the files...
[18:08] <zumbrunn> usually that would be done by adding a property that refers to a file that is stored statically
[18:09] <zumbrunn> since you likely would need to control access to that file dynamically, you would use res.forward for that
[18:09] <zumbrunn> http://helma.zumbrunn.net/reference/res.html#forward
[18:12] <zumbrunn> and yes, the db stores properties that are not specified in type.properties
[18:13] <zumbrunn> btw, note that currently, object and array properties are *not* automatically serialized and are *not* persisted
[18:14] <zumbrunn> that's where the new onPersist method is a really exciting addition :-)
[18:17] <midnightmonster> oh... so this.tags = ['a','b','c'], but this.tags won't exist when I pull it back from the db unless I make it?
[18:18] <midnightmonster> am I right in thinking I'll have to fake an onDelete action?
[18:19] <zumbrunn> yes, until now I had to work around that using a custom method that serializes the property
[18:19] <zumbrunn> not sure regarding onDelete, but probably so
[18:20] <midnightmonster> you still have to do that, right? just in onPersist/onInit
[18:22] <zumbrunn> yes, but that's much better than having to use methods this.setMyProp('foo', value) and then having to read it with a custom method like that as well
[18:22] <midnightmonster> e.g.,
[18:22] <midnightmonster> function onPersist(){ this.tags = this.tags.toJSON(); } function onInit(){ this.tags = eval(this.tags); }
[18:22] <midnightmonster> right?
[18:23] <zumbrunn> exactly
[18:35] <midnightmonster> or more generically
[18:35] <midnightmonster> function onPersist(){ var i, ap; ap = []; for(i in this){ if(this[i] instanceof Array){ ap.push(i); this[i] = this[i].toJSON(); } } this._arrayProperties = ap.toJSON(); }
[18:35] <midnightmonster> function onInit(){ var ap = eval(this._arrayProperties); var that = this; ap.forEach(function(i){ that[i] = eval(that[i]); }); }
[18:49] <midnightmonster> welcome leobm
[19:41] <midnightmonster> chris, I'm stuck on something that I presume is actually trivial
[19:42] <midnightmonster> suppose I want /users to display a list of my users, and /users/joe to display the details of my user named joe (and /users/bob, and /users/jim, etc.)
[19:43] <midnightmonster> how do I setup the map of address to objects?
[19:47] <midnightmonster> I can figure out how to do the list at /users as an action of Root if Root has users = collection(User), and I can see how to get a particular user to display if /users is a Users object with _children = collection(User), but I can't figure out how to get both behaviors.
[19:48] <midnightmonster> I would like to have the list of all users simply be the main.hac of my Users object, but I don't understand how to get a single Users object to be a child of Root
[19:52] <leobm> hi
[20:00] <midnightmonster> hi leobm--don't suppose you know the answer to my question?
[20:01] <leobm> not 100% but I think you define you collection like: _children = collection(User) ?
[20:01] <leobm> in type.properties ?
[20:02] <midnightmonster> yeah, I know how to do that
[20:02] <leobm> than you can use the property _children.accessname = username
[20:02] <leobm> to access an object by his username attribute
[20:02] <leobm> e.g.
[20:03] <midnightmonster> yeah, got that too. what I don't know is how to make /users/ map to a single Users object the way / maps to a single Root object
[20:03] <leobm> this collection do you define in the root object.
[20:03] <leobm> than you loop about the collection and show the userlist.
[20:04] <leobm> for every user object you display in the list you create a href of this object
[20:04] <leobm> http://helma.org/stories/47674/
[20:04] <leobm> HopObject.href()
[20:05] <midnightmonster> I could do that, but then whence comes the intermediate /users or /stories object?
[20:05] <leobm> if you setup the accessname this method should create a link like user/username
[20:08] <leobm> ok, this was now a simple example. for complicated object relation look at the mountpoint value for an attribute
[20:08] <midnightmonster> ?
[20:09] <leobm> I think a good start for this is the antville source code.
[20:09] <leobm> http://adele.helma.org/source/viewcvs.cgi/antville/code/Root/type.properties?rev=1.21&cvsroot=apps&content-type=text/vnd.viewcvs-markup
[20:10] <midnightmonster> ha!
[20:10] <midnightmonster> thanks, that's exactly what I was looking for
[20:10] <leobm> I'm learnign helma too. I'm not a profi and can't good explain it. buit with the antville code I learned the features of helma to user
[20:10] <leobm> I'm learnign helma too. I'm not a profi and can't good explain it. buit with the antville code I learned the features of helma to use
[20:14] <midnightmonster> thanks, though--that was just what I needed. Didn't know about the mountpoint() thing
[20:31] <midnightmonster> do you know what these lines from that source code do?
[20:31] <midnightmonster> sys_frontSite = object(Site)sys_layout = object(Layout)
[20:32] <midnightmonster> I mean:
[20:32] <midnightmonster> sys_frontSite = object(Site)
[20:32] <midnightmonster> sys_layout = object(Layout)
[20:38] <leobm> not really. but I think you create an instance of the prototype and with the name on the left site you can access this object ...
[20:38] <leobm> but I'm not shure.
[20:40] <midnightmonster> that's what it looks like it should be, but my first attempt at what I just started using mountpoint for was to do users = object(Users) and return this.users from getChildElement('users'), but it didn't work
[20:43] <leobm> I think object is only for one object. not a list of objects.
[20:43] <midnightmonster> I know--that was what I wanted
[20:44] <leobm> for lists of objects you need the collection keyword
[20:44] <midnightmonster> I know
[20:44] <midnightmonster> I only need one Users object that manages all the individual User objects.
[20:45] <midnightmonster> users = mountpoint(Users) did what I needed
[20:45] <leobm> for this I would user manager. look at the antrville code. they user this here :
[20:45] <leobm> members = mountpoint(MemberMgr)
[20:45] <leobm> use manager
[20:46] <midnightmonster> That actually might be a better name
[20:46] <leobm> this manager is now reachable by /members/ in the url
[20:46] <midnightmonster> yes, that's what I'm doing since you showed me the source. the only difference is in how I named my class
[20:46] <midnightmonster> class=prototype
[20:48] <leobm> this manager has collections of Membership
[20:49] <leobm> and in a Memebership you have an user Object
[22:03] <midnightmonster> I'm thinking I'm not going to use templates at all but instead do something like http://elzr.com/posts/hyperscript
[22:31] <earl> w
[22:42] <midnightmonster> w?
[23:32] <midnightmonster> in the midst of thinking about and trying to implement a way to represent html in script more efficiently than w/ standard templates, I suddenly remembered the existence of E4X.
[23:33] <midnightmonster> I've never used it before, and documentation is sparse, but this is seriously the best new feature I have ever seen in any language
[23:37] <doublec> the problem with e4x for generating html is it actually generates xml
[23:37] <doublec> so <script ....></script> becomes <script .../>
[23:37] <doublec> which most browsers ignore
[23:39] <doublec> See here: http://groups.google.com/group/mozilla.dev.tech.js-engine/browse_thread/thread/b96526beaae9c3c9/d9d4357e1701ac10
[23:41] <midnightmonster> yeah. easy to workaround, though, as others have noted. actually you can put anything you want inside a <script src="..."> tag--the content is ignored
[23:43] <doublec> that issue aside, I agree that E4X is very nice
[23:44] <midnightmonster> you're likely to find <textarea>'s are also a problem, and that's more complicated.

 

 

In the channel now:

Logs by date: