14 Oct, 2008, Thresius wrote in the 1st comment:
Votes: 0
Hello everyone,

I'm just looking for a little bit of advice. I'm relatively new to Ruby and trying to get to grips with the language as best as possible. I've been doing good up until now and now I'm stumped. Besides the fact that I have never did anything like this before, it is even worse trying to do it in a language that is relatively new to you.

I'm looking to create a verb-like system for commands. Using formats applied to commands I should be able to define a format like so:

SAY TO 1=% IN 2=%


Like it says, it takes the arguments passed to a search function and compares it to the format to see if it is true. 1=% and 2=% being the arguments that are passed. The function will then pass back the command to be executed and the arguments to be passed where 1=% is equal to 'Ologo' for instance. Obviously the arguments would be an array.

So any ideas would be great! Thank you.
14 Oct, 2008, David Haley wrote in the 2nd comment:
Votes: 0
Just to be sure the problem is clear: you just want to take a regular expression, and match it against some input text, and see if it matches, correct? Or is there something more complicated going on? I ask because if it's what said, you can use Ruby pattern matching pretty easily to accomplish this.

There are more or less efficient ways of implementing that; the simplest (and not very efficient) way is to just have a list of regular expressions and try each one in turn.
14 Oct, 2008, Thresius wrote in the 3rd comment:
Votes: 0
Ideally what I want it to do is iterate through a list of commands and match their formats (like the one supplied) above to the input passed to the function… we'll call that search_commands(). But it is a twofold function were it also returns back the command and arguments.

cmd, args = search_commands(some_string)


But yes, ideally I want it to patern match to an extent, but what happens in this situation. We have the first argument of the example above 1=%, which only needs a single word for an argument.. but the second argument can be more than one word, maybe even a whole couple of sentences just like a normal say would pass. Therefore that is were patterns are failing me I think.

So it needs to match the format of the input with the format of the command, and then extract the arguments from the input and pass them back.

That a little clearer. Sorry if I am making little sense, it is rather late at night! :redface:
14 Oct, 2008, David Haley wrote in the 4th comment:
Votes: 0
Are you familiar with the concept of pattern captures? What you're described is a very common place where they're used. E.g., in Perl,

/foo (.*) bar/

this will match any string that starts with "foo ", ends in " bar", and will capture everything in between (to the variable $1 in Perl's case).

I know that Ruby has similar functionality for string matches and captures, but I can't remember it off the top of my head. Basically you want to look for their pattern matching or regular expression library, and look at how to do captures. The result will be (1) whether or not the pattern matched, and (2) an array of captures.
14 Oct, 2008, Thresius wrote in the 5th comment:
Votes: 0
Okay, that sounds good to be. Looked that up for Ruby at it appears to basically be the same thing.

It would be easy enough to do this, which captures the arguments in an array:

str = "say to 1=* in 2=* 3=*"
m = str.scan(/(\d+=\*)/i)


That finds all the arguments in the format, but then how would I get the values from the input to match these. That is probably what I'm more stuck at that anything. I won't say I'm good at regular expressions and never did anything surrounding this before.

Edit: What I should say actually is, it is only finding the patterns on the format, but I need to check for the arguments in the input as well as the format. It needs to recognize that:

SAY TO OLOGO IN ELVISH HELLO THERE, HOW ARE YOU?
is equal to…
SAY TO 1=* IN 2=* 3=*


where the arguments are just been stripped out of the input and put into an array which can be passed back to the interpreted before calling the command.

1=Ologo
2=Elvish
3=Hello there, how are you?
14 Oct, 2008, Thresius wrote in the 6th comment:
Votes: 0
Nevermind, I have managed to solve the problem and it works just perfectly!

Thanks very much for replying to my thread though, you have been a massive help :)
15 Oct, 2008, Vassi wrote in the 7th comment:
Votes: 0
That's an interesting approach, I always isolate the command first before I match the patterns, but then my commands (to date) tend to be positional so I usually just split by whitespace and check lengths.

Edit: actually, I lied, I do use regular expressions for room targeting commands for cases of ##, such as backstab rabbit#2, sneak door#2, etc

Second Edit: I don't want to derail the thread too much, but it seems to be resolved so I'll do it anyway. What are ruby's strength's, exactly? It must have a claim to fame other than Rails (though truth be told I don't really know what Rails is other than a web framework whose scalability is questionable). The reason I ask is because Ruby is eventually going to join IronPython as a mature DLR language, so if I can use it I'll probably start looking into it.
15 Oct, 2008, quixadhal wrote in the 8th comment:
Votes: 0
This is cheating, since it uses an external object, but here's a nice chat server in ruby.

I think of ruby as what perl might have been, had objects been a big deal, and had someone wanted to make it readable instead of looking like sendmail.cf.

#!/usr/bin/ruby -w
# chat.rb
require 'gserver'

class ChatServer < GServer

def initialize(port=4000, host=GServer::DEFAULT_HOST)
@clients = []
super(port, host, Float::MAX, $stderr, true)
end

def serve(sock)
begin
@clients << sock
hostname = sock.peeraddr[2] || sock.peeraddr[3]
@clients.each do |c|
c.puts "#{hostname} has joined the chat." unless c == sock
end
until sock.eof? do
message = sock.gets.chomp
break if message == "/quit"
@clients.each { |c| c.puts "#{hostname}: #{message}" unless c == sock }
end
ensure
@clients.delete(sock)
@clients.each { |c| c.puts "#{hostname} has left the chat." }
end
end
end

server = ChatServer.new(*ARGV[0..2] || 4000)
server.start(-1)

while true do
sleep 2
puts "tick"
end

server.join
15 Oct, 2008, Vassi wrote in the 9th comment:
Votes: 0
it looks like VB ran into Python and they made babies =(

I hate VB syntax….so much
15 Oct, 2008, Runter wrote in the 10th comment:
Votes: 0
I dunno. I don't like VB at all but I do like ruby.
15 Oct, 2008, Vassi wrote in the 11th comment:
Votes: 0
Runter said:
I dunno. I don't like VB at all but I do like ruby.


Indeed, I was mostly being facetious. I don't know what it is about VB though, that drives me insane. I want to claw somebody's eyes out if I have to look at VB and translate it to C#.

Mostly I was referring to the Begin and End thing, the syntax in general looks friendly for scripters, especially beginning ones (begin, end, unless etc) but the lack of symmetry that braces provide really messes with me.
15 Oct, 2008, David Haley wrote in the 12th comment:
Votes: 0
Eh, I wouldn't consider that "begin" and "end" are necessarily a beginner's thing. It's just a question of habit. And actually, the "unless" construct is fairly useful in some cases, even though I tend to think that the condition should usually come first to avoid seeing the statement part as an unconditional statement.
15 Oct, 2008, Cratylus wrote in the 13th comment:
Votes: 0
VB considered harmful.

-Crat
15 Oct, 2008, Vassi wrote in the 14th comment:
Votes: 0
DavidHaley said:
Eh, I wouldn't consider that "begin" and "end" are necessarily a beginner's thing. It's just a question of habit. And actually, the "unless" construct is fairly useful in some cases, even though I tend to think that the condition should usually come first to avoid seeing the statement part as an unconditional statement.


Technically I said it's friendly for beginners, not that it was for beginners. -grins- I've tried to teach a 'scripting' language to people before, like some basic PHP, and some people have real issues understanding why they need to have 'all those dumb brackets'. For them, begin and end would be more intuitive - whether or not it was intended that way is another story.
15 Oct, 2008, quixadhal wrote in the 15th comment:
Votes: 0
Actually, this line
@clients.each { |c| c.puts "#{hostname}: #{message}" unless c == sock }
is more perl-like. :)
It also lets you do the good old "puts foo if player == dork" type of construct.
15 Oct, 2008, David Haley wrote in the 16th comment:
Votes: 0
Vassi: oh, yeah, I misread your sentence :smile: Every time I've taught intro programming, if people don't like the braces I just tell them to accept it as a fact of life and move on. Actually, you can provide fairly good analogies for it; it is kind of like bullet lists in text.

Actually, I'm not a huge fan of "begin" because most of the time it's redundant. The "end" however is useful.

And I really like the block construct that Ruby uses, even though too many people assume it's a feature unique to or created by Ruby. :wink:
0.0/16