io language - and Ruby
Posted by Karagy
on Mon 22 May 2006 05:34 AM
— 19 posts, 71,431 views.
Hi Nick.
What you mean about subj?
see
http://www.iolanguage.com/
I'm not sure I understand your post. Are you suggesting that Nick include support for scripting in this 'Io' language?
I have moved this thread into the "suggestions" part of the forum, as I couldn't see what it had to do with Lua.
I checked out that site, I gather Io is another scripting language (inspired in part by Lua it says).
Assuming you are asking for support for it in MUSHclient, as far as I can see from their site, there is no well-documented method of incorporating it into C programs (unlike the Lua documentation which is very good in that respect).
Unless they release an interface using the Microsoft Scripting Interface (like VBscript, Jscript, Pythonscript and so on) I can't see it being practical to incorporate it into MUSHclient.
If the ActiveScripting Interface is all you need, then perhaps you should also consider using Ruby. Ruby is my (current) favourite for programming in general, and I use it on another client for my mud scripts.
Can you give me the link to the Ruby script engine please?
Windows installer for ruby:
http://rubyinstaller.rubyforge.org/wiki/wiki.pl
And the normal website:
http://www.ruby-lang.org/en/
I don't think those are what Nick wants; what I think he wants is the ActiveScript binding, not the general language:
http://raa.ruby-lang.org/project/asr/
I know it's bad form to preach on a forum, but I have to say, if you're learning Object Orientated programming and are struggling, Ruby is a great language to help you. It's strongly object-orientated, it's wonderfully simple to both learn and use, and you will learn a great deal about classes and OO programming (and algorithms). It uses inheritance and 'ancestry' in a simple yet powerful way and (IMHO) makes it very easy to understand complex concepts in OO programming.
End bad form.
OK, I'll take a look at seeing if it works with MUSHclient.
I have had previous experiences where the Active Script implementation doesn't work properly, but we'll see.
I note from the examples at their web site that it looks remarkably similar in some ways to Lua (in function declarations for example).
It's probably a mix of Perl, Python, and Lua in syntax. Ruby is said to look almost exactly like Python if you indent it properly and strip the ends, but it would also look exactly like Lua if you replace defs with functions :)
Well I almost have Ruby working - excepting exporting functions from the script file. For example:
<triggers>
<trigger
enabled="y"
match="Darkhaven"
name="triggername"
regexp="y"
script="mytrigger"
sequence="100"
>
</trigger>
</triggers>
This is trying to call "mytrigger" script, and this is in my script file:
def mytrigger (name, line, wildcards)
@world.Note (name)
@world.Note (line)
end
It compiles OK, but says "The trigger (triggername) subroutine named "mytrigger" could not be found.".
Any clues about how to make the RubyScript engine make the function "mytrigger" available externally?
Well, I can't see why it can't be found, however when I installed rubyscript I noticed a weird... thing. I actually have 2 options for ruby scripting languages: GlobalRubyScript.1 and RubyScript.1
I don't know why this is, nor do I know the difference between them - however, I do know that the GlobalRubyScript.1 gives me lots of errors and weird bugs when I use it for my scripts, but if I use RubyScript.1 everything compiles and works just fine.
I also don't know how your program is written, or what language it's written in, but in the source code I've seen, it uses the "ParseScriptText" function of the activescripting engine to handle the script, and that works just fine for my ruby scripts. I have no idea why you would get a 'function not found' error though.
There's an ebook that's used to help people with ruby - it's pretty comprehensive. I've used it for all my ruby programming to date. I can't remember the exact url, but it's on the ruby website somewhere, and it tells you how to extend ruby to other languages and how to link the two together - maybe that will help you.
I use RubyScript which sounds like what you are using (without the .1), and I think internally I call ParseScriptText for all the script languages (except Lua).
The problem is not that it parses badly, but it doesn't seem to export the function as an external callable function.
From what I can see mytrigger will be a local function, which perhaps is not exported, however trying to make a global function doesn't parse, eg.:
def $mytrigger (name, line, wildcards)
@world.Note (name)
@world.Note (line)
end
I am not enough of a Ruby expert to know what, if anything, I am doing wrong, and how to fix it.
I'm not an expert either, and as far as I can tell, your script looks syntactically fine (except for making a global function using $). The only thing I can think of is maybe it's declaring the function as private, when it should be declared as public. However, according to the documentation, all methods are public by default. Try declaring it as public, just in case - frankly I doubt that's the problem though.
If all else fails, you have a couple of things you can try. If you set the scripting language to ruby, and define a function in the scriptfile, does that work (ie. without going through the trigger framework)? It's possible that for some reason your scripting engine is causing some kind of problem, email me and I can give you a few things to test out. There's a whole bunch of stuff that ruby can do to help you with debugging, but since I don't know what's failing and where, I can't really offer any advice. As far as I know, the script you wrote should work.
If you wish to send me the ruby-enabled version so I can test it, that'd be okay too (although I'm not sure how much time I can put into it or how much help it'll be).
Quote:
If you set the scripting language to ruby, and define a function in the scriptfile, does that work (ie. without going through the trigger framework)?
Hmmm - when I first tested this it worked:
@world.Note "test" # --> echoes "test"
However this doesn't:
def test()
@world.Note "hi there"
end
test() # --> error: wrong number of arguments
Not sure what this is about. The same code running in the stand-alone version works (replacing @world.Note by print).
It gets a bit weirder. I thought maybe "test" was some kind of reserved word, so I re-did it using nickgammon as the function name. I guess that isn't a reserved word :P .
def nickgammon()
# @world.Note "hi there"
end
nickgammon() # --> undefined method `nickgammon' for #<Module:0x1b65038>
Well, I just defined it right there! And if my syntax is wrong, how come "test" works? Again, that works in the stand-alone version:
def nickgammon()
print "oops"
end
nickgammon() # --> "oops"
Very weird. Clearly it's working on the engine ok, otherwise @world.note wouldn't work. There must be some issue to do with scoping and function declarations. I've never seen it do anything like this before though.
Yes, test is reserved (well, not reserved, it's defined in the kernel module and is similar to the linux test command for finding out information about files).
Okay, try this. Stuff works ok without defining a function right? To double check this, make a few variables, change them around a bit, and double check that everything works ok. I'm confident it willl, but when I'm debugging stuff like this I always like to go very slowly and very thoroughly.
If that's ok, then try defining a function, like your previously mentioned nicgammon function, but instead of trying to call it from within the script, can you call it from the source code using ParseScriptText() ? I realise it's a kludge, but I'm struggling to figure out why a defined function isn't being found.
Is there any chance you could send me the modified binary (or dll, or whatever) that has ruby working, so I can play around with it myself? (I love to fiddle).
Oh, one thing I just thought of. I think ruby is a bit like C++, in that it tries to find functions that take the correct number of arguments. It's possible that there are arguments being thrown in somehow, and since your function doesn't accept arguments, it says it can't be found.
What about if you defined a few more functions that have 1, 2, 3 and 4 arguments, and then you can figure out which one is being called.
Also, there is some easy ways to get debug information about which functions are available.
if you do something like this in your script:
def ng
@World.note "hi"
end
@world.note("Public methods:\n")
@world.note(public_methods + "\n")
@world.note("Private methods:\n")
@world.note(private_methods + "\n")
@world.note("Protected methods:\n")
@world.note(protected_methods + "\n")
This will print out all methods that are public, private, and protected. You'll probably get alot of them, but you're looking to find the "ng" one. It *should* be in the public methods list (when I tested it using the ruby interpreter, that's where I found it), but if it's not showing up there, that may indicate a problem.
That's all I can think of for now.
That didn't really work.
Look, it seems to me that the Ruby Active Script interface isn't working, plain and simple.
I have had similar problems in the past with things like PHP and Tcl. The initial implementations weren't perfect, and after they got up to about a year in, it would work, with no effort on my part.
Internally in MUSHclient the only difference between the script interface for (say), VBscript and JScript is simply the string that is supplied to instantiate the script engine. After that it should work. Since 6 script engines already work fine (plus Lua which doesn't use Active Scripting) I think I can say that the MUSHclient script interface is working OK.
Anything's possible.
I, however, have ruby installed and have another client that uses the (presumably) same scripting interface, and ruby works just fine for me in that program. I also have perl, vbscript, and java as options for the scripting language of that other program, and they all work fine too.