Discussion:
regex question
(too old to reply)
r***@yahoo.com
2007-11-01 18:31:03 UTC
Permalink
Note: parts of this message were removed by the gateway to make it a legal Usenet post.

I have a string = "this is text that I want to 9 9.90 89 9 ii8 u"

using str = string.gsub(/(?!\d)\b\s\b(?!\d)/,'-')

i get "this-is-text-that I want-to 9 9.90 89 9-ii8-u"
^ ^

there problem is that I do not want the "-" to show up if the last char is a digit or the first chat is a digit. Got real close, but I think I need lookbehind which is not supported in ruby?

------------------------------
Robert Keller
***@yahoo.com
j***@weirichhouse.org
2007-11-01 19:20:23 UTC
Permalink
Post by r***@yahoo.com
I have a string = "this is text that I want to 9 9.90 89 9 ii8 u"
using str = string.gsub(/(?!\d)\b\s\b(?!\d)/,'-')
i get "this-is-text-that I want-to 9 9.90 89 9-ii8-u"
^ ^
there problem is that I do not want the "-" to show up if the last char
is a digit or the first chat is a digit. Got real close, but I think I
need lookbehind which is not supported in ruby?
Is this what you want:

str.gsub(/([^0-9])\b\s\b([^0-9])/) { "#$1-#$2" }

-- Jim Weirich
--
Posted via http://www.ruby-forum.com/.
b***@yahoo.com
2007-11-01 20:10:32 UTC
Permalink
Post by j***@weirichhouse.org
str.gsub(/([^0-9])\b\s\b([^0-9])/) { "#$1-#$2" }
Or simply:

new_str = str.gsub(/([a-zA-Z]) ([a-zA-Z])/) {"#$1-#$2"}
puts new_str

--output:--
this-is-text-that I want-to 9 9.90 89 9 ii8 u
--
Posted via http://www.ruby-forum.com/.
b***@yahoo.com
2007-11-02 01:54:06 UTC
Permalink
Post by b***@yahoo.com
Post by j***@weirichhouse.org
str.gsub(/([^0-9])\b\s\b([^0-9])/) { "#$1-#$2" }
new_str = str.gsub(/([a-zA-Z]) ([a-zA-Z])/) {"#$1-#$2"}
puts new_str
--output:--
this-is-text-that I want-to 9 9.90 89 9 ii8 u
You can also write it this way, which I think is even simpler since that
block might be a little confusing:

new_str = str.gsub(/([a-zA-Z]) ([a-zA-Z])/, '\1-\2')
--
Posted via http://www.ruby-forum.com/.
r***@yahoo.com
2007-11-01 22:59:28 UTC
Permalink
Note: parts of this message were removed by the gateway to make it a legal Usenet post.

Perfect! Thanks. I really got to get a better handle or regular expressions

------------------------------
Robert Keller
***@yahoo.com

----- Original Message ----
From: 7stud -- <***@yahoo.com>
To: ruby-talk ML <ruby-***@ruby-lang.org>
Sent: Thursday, November 1, 2007 3:10:32 PM
Subject: Re: regex question
Post by j***@weirichhouse.org
str.gsub(/([^0-9])\b\s\b([^0-9])/) { "#$1-#$2" }
Or simply:

new_str = str.gsub(/([a-zA-Z]) ([a-zA-Z])/) {"#$1-#$2"}
puts new_str

--output:--
this-is-text-that I want-to 9 9.90 89 9 ii8 u
--
Posted via http://www.ruby-forum.com/.
j***@yahoo.com
2007-11-05 22:24:53 UTC
Permalink
(I thought I had sent in my solution yesterday, but it didn't send, since I didn't realize that Yahoo now sometimes demands a CAPTCHA.)


I've been busy these past few weeks, and thus didn't get around to this quiz until yesterday (Hurrah for the extension!). Even then, I only implemented the minimum (save for the inspect/to_s method to make testing easier, which doesn't count).

My solution uses a doubly-linked list of lines. Each line is guaranteed to be terminated by a newline; each newline is guaranteed to terminate a line. This means that strings that don't end in a newline will have one added.

The cursor should be thought to lie between two characters rather than on a character. Because of this, insertign before and after is the same. The cursor is represented by the node containing the line that the cursor is on, and the index of the character to the right of the cursor.

All insertions and deletions should be O(n), where n is the length of the line. Moving the cursor should be O(1).

class ListNode
attr_accessor :prev,:nxt,:val

def initialize(prev=nil,nxt=nil,val="")
@prev,@nxt,@val = prev,nxt,val
end

def to_a
first = self
first = first.prev while first.prev

arr = []
node = first
while node.nxt
arr << node
node = node.nxt
end
arr << node
arr
end
end


###Partitions string into a linked list of lines
###For all lines, the last character is guaranteed to be a newline
###That includes the last, for simplicity's sake
###
###The cursor is between characters rather than on a character. Thus, inserting after
###is the same as inserting before
class LinkedListBuffer
def initialize(str="")
str << "\n" unless str[-1,1] == "\n"
list = str.scan(/[^\n]*?\n/).map{|s| ListNode.new(nil,nil,s)}
list.each_with_index do |node, idx|
node.prev = list[idx-1] unless idx == 0
node.nxt = list[idx+1]
end
@cur_line = list.first
@line_idx = 0
end

def at_end?
!@cur_line.nxt and @line_idx == @cur_line.val.length-1
end

def at_begin?
!@cur_line.prev and @line_idx == 0
end

##The construct ""<<ch is used so that ch may be either a string or an integer

def insert(ch)
unless "\n" == "" << ch
@cur_line.val[@line_idx,1] = ""<<ch<<@cur_line.val[@line_idx]
else
@cur_line.val[@line_idx,1] = ""<<ch<<@cur_line.val[@line_idx]
line = ListNode.new(@cur_line,@cur_line.nxt,@cur_line.val.slice!((@line_idx+1)..-1))
@cur_line.nxt.prev = line if @cur_line.nxt
@cur_line.nxt = line
end
end

def del_after
unless @cur_line.val[@line_idx] == ?\n or at_end?
@cur_line.val.slice!(@line_idx,1)
else
if at_end?
nil
else
@cur_line.val[-1,1] = @cur_line.nxt.val
@cur_line.nxt = @cur_line.nxt.nxt
"\n"
end
end
end

def del_before
unless at_begin?
cursor_left
del_after
else
nil
end
end

def cursor_left
if at_begin?
nil
elsif @line_idx == 0
@cur_line = @cur_line.prev
@line_idx = @cur_line.val.length-1
"\n"
else
@line_idx -= 1
@cur_line.val[@line_idx,1]
end
end

def cursor_right
if at_end?
nil
elsif @line_idx + 1 == @cur_line.val.length
@line_idx = 0
@cur_line = @cur_line.nxt
"\n"
else
@line_idx += 1
@cur_line.val[@line_idx-1,1]
end
end

def cursor_up
if @cur_line.prev
@cur_line = @cur_line.prev
@line_idx = [@line_idx,@cur_line.val.length-1].min
else
nil
end
end

def cursor_down
if @cur_line.nxt
@cur_line = @cur_line.nxt
@line_idx = [@line_idx,@cur_line.val.length-1].min
else
nil
end
end

def to_s
@cur_line.val = @cur_line.val[***@line_idx]+"|"+@cur_line.val[@line_idx..-1]
str = @cur_line.to_a.map{|node| node.val}.join
@cur_line.val.slice!(@line_idx)
str
end
alias inspect to_s
end


__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Eric Mahurin
2007-11-06 20:13:53 UTC
Permalink
Post by j***@yahoo.com
My solution uses a doubly-linked list of lines. Each line is guaranteed to be terminated by a newline; each newline is guaranteed to terminate a line. This means that strings that don't end in a newline will have one added.
I'm glad to see a linked-list solution. Another approach to use is to
leave the newlines out of the "lines". Newlines would be implied to
be between them (no implied newline after the last line).
Post by j***@yahoo.com
The cursor should be thought to lie between two characters rather than on a character. Because of this, inserting before and after is the same. The cursor is represented by the node containing the line that the cursor is on, and the index of the character to the right of the cursor.
Actually, they are different. Both insert the character at the same
point in the text. The difference is the final position of the
cursor/caret. insert_after is not a normal editor operation though.
It is equivalent to typing right-to-left instead of left-to-right
(what insert_before does). Since insert_after isn't a common
operation, and it can be done using insert_before followed by left, it
isn't needed. The main reason I threw it in was symmetry.
Post by j***@yahoo.com
All insertions and deletions should be O(n), where n is the length of the line. Moving the cursor should be O(1).
You could make it completely O(1) by using something like a gap buffer
for a line (or while editing one). But, it may not matter too much as
long as the line size is small enough (ruby overhead may dominate the
O(n) C code).

Also, the API given in the quiz was really only meant to be a
suggestion. Your implementation is probably better off taking a
string instead of a character to insert.

Eric
James Koppel
2007-11-06 20:39:48 UTC
Permalink
Post by Eric Mahurin
Post by j***@yahoo.com
The cursor should be thought to lie between two characters rather
than on a character. Because of this, inserting before and after is the
same. The cursor is >>represented by the node containing the line that the
cursor is on, and the index of the character to the right of the
cursor.
Post by Eric Mahurin
Actually, they are different. Both insert the character at the same
point in the text. The difference is the final position of the
cursor/caret. insert_after is not a normal editor operation though.
It is equivalent to typing right-to-left instead of left-to-right
(what insert_before does). Since insert_after isn't a common
operation, and it can be done using insert_before followed by left, it
isn't needed. The main reason I threw it in was symmetry.
Actually, I wouldn't call it different. I prefer just to call "inserting a character" adding a character at the position of the cursor. If you want the cursor to end up at the right, I'd call that a second operation.

(One could probably have an argument all day over whether the One True Name for this is "insert_before" or "insert followed by cursor_right" with no movement toward consensus.)


__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Isaac Gouy
2007-11-06 23:07:35 UTC
Permalink
Many people believed we'd never be faster than the C
implementation,
and many still think we're slower. Now that I've set that record
straight, any questions?
1. How long will it be before Alioth has some *reasonable* numbers
=20
for jRuby? As of yesterday, they still have you significantly =20
slower than MRI. So I need to take jRuby out of my slides for =20
RubyConf :) ... I
The current published Alioth numbers are based on JRuby 1.0(ish),
which
was generally 2-3x slower than MRI. I'm hoping the numbers will be
updated soon after the 1.1 releases...but it probably won't happen
until 1.1 final comes out in December. If someone else wants to
re-run
them for us, it would make us very happy :)
An "Update Programming Language" "Feature Request" will usually get our
attention.


Coincidentally, I did grab 1.1b1 so the benchmarks game has new
measurements

http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=jruby



__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Roger Pack
2007-11-06 23:38:42 UTC
Permalink
Post by Isaac Gouy
Coincidentally, I did grab 1.1b1 so the benchmarks game has new
measurements
http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=jruby
Wow it would appear that jruby is indeed faster, and indeed uses a lot
more memory :) (or maybe that's just startup overhead). thanks for a
good program!
--
Posted via http://www.ruby-forum.com/.
Charles Oliver Nutter
2007-11-07 02:35:00 UTC
Permalink
Post by Roger Pack
Post by Isaac Gouy
Coincidentally, I did grab 1.1b1 so the benchmarks game has new
measurements
http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=jruby
Wow it would appear that jruby is indeed faster, and indeed uses a lot
more memory :) (or maybe that's just startup overhead). thanks for a
good program!
It's another well-known fact about running on the JVM that we have to
suck it up and accept there's an initial memory chunk eaten up by every
JVM process. If one excludes that initial cost, most measurements have
us using less memory than C Ruby...so for very large apps we end up
coming out ahead. But for small, short apps, the initial slow startup
and high memory usage is going to be a battle we fight for a long time.

- Charlie
Roger Pack
2007-11-07 03:31:32 UTC
Permalink
Post by Charles Oliver Nutter
It's another well-known fact about running on the JVM that we have to
suck it up and accept there's an initial memory chunk eaten up by every
JVM process. If one excludes that initial cost, most measurements have
us using less memory than C Ruby...so for very large apps we end up
coming out ahead. But for small, short apps, the initial slow startup
and high memory usage is going to be a battle we fight for a long time.
- Charlie
If you run multiple threads I assume there isn't an extra memory cost
for that--is that right?
--
Posted via http://www.ruby-forum.com/.
Clifford Heath
2007-11-07 04:27:23 UTC
Permalink
Post by Roger Pack
If you run multiple threads I assume there isn't an extra memory cost
for that--is that right?
Every thread is going to need its own stack, but that'll be small
compared to the startup overhead. I'm sure Charles will elaborate.

I'm guessing that JRuby still doesn't support continuations...? I
think that would require the "spaghetti stack" model, which would
remove most of the per-thread initial stack overhead.

Clifford Heath.
Charles Oliver Nutter
2007-11-07 07:26:54 UTC
Permalink
Post by Clifford Heath
Post by Roger Pack
If you run multiple threads I assume there isn't an extra memory cost
for that--is that right?
Every thread is going to need its own stack, but that'll be small
compared to the startup overhead. I'm sure Charles will elaborate.
Our threads will be a lot more expensive than Ruby's, but a lot cheaper
than a separate process in either world.
Post by Clifford Heath
I'm guessing that JRuby still doesn't support continuations...? I
think that would require the "spaghetti stack" model, which would
remove most of the per-thread initial stack overhead.
Our official stance is that JRuby won't support continuations until the
JVM does. We could emulate them by forcing a stackless implementation,
but it would be *drastically* slower than what we have now.

- Charlie
Charles Oliver Nutter
2007-11-07 07:26:54 UTC
Permalink
Post by Roger Pack
Post by Charles Oliver Nutter
It's another well-known fact about running on the JVM that we have to
suck it up and accept there's an initial memory chunk eaten up by every
JVM process. If one excludes that initial cost, most measurements have
us using less memory than C Ruby...so for very large apps we end up
coming out ahead. But for small, short apps, the initial slow startup
and high memory usage is going to be a battle we fight for a long time.
- Charlie
If you run multiple threads I assume there isn't an extra memory cost
for that--is that right?
Yes, generally. They won't be as light as Ruby's green threads, but then
Ruby's threads can't actually run in parallel anyway.

- Charlie
Charles Oliver Nutter
2007-11-07 07:29:03 UTC
Permalink
Post by Roger Pack
Post by Isaac Gouy
Coincidentally, I did grab 1.1b1 so the benchmarks game has new
measurements
http://shootout.alioth.debian.org/gp4sandbox/benchmark.php?test=all&lang=jruby
Wow it would appear that jruby is indeed faster, and indeed uses a lot
more memory :) (or maybe that's just startup overhead). thanks for a
good program!
I just committed an addition to JRuby that allows you to spin up a
"server" JRuby instance (using "Nailgun") in the background and feed it
commands. See the startup difference using this:

normal:

~/NetBeansProjects/jruby $ time jruby -e "puts 'hello'"
hello

real 0m1.944s
user 0m1.511s
sys 0m0.138s

nailgun:

~/NetBeansProjects/jruby $ time jruby-ng -e "puts 'hello'"
hello

real 0m0.103s
user 0m0.006s
sys 0m0.009s

Here's a post from the JRuby list describing how to use this, for those
of you that are interested. Also, this allows you to avoid the startup
memory cost for every command you run since you can just issue commands
to that running server and it will re-use memory. After running a bunch
of commands on my system, that server process was still happily under
60M, and never went any higher.

..

I've got Nailgun working with JRuby just great now.

bin/jruby-ng-server
bin/jruby-ng

If you want to use the server, say if you're going to be running a lot
of command-line tools, just spin it up in the background somewhere.

jruby-ng-server > /dev/null 2> /dev/null &

And then use the jruby-ng command instead, or alias it to "jruby"

alias jruby=jruby-ng

You'll need to make the ng client command on your platform, by running
'make' under bin/nailgun, but then everything should function correctly.

jruby-ng -e "puts 'here'"

The idea is that users will have a new option to try. For JRuby, where
we have no global variables, no dependencies on static fields, and
already depend on our ability to spin up many JRuby instances in a
single JVM, this ends up working very well. It's building off features
we already provide, and giving users the benefit of a fast,
pre-initialized JVM without the startup hit.

I think we're probably going to ship with this for JRuby 1.1 now. It's
working really well. I've managed to resolve the CWD issue by defining
my own "nailMain" next to our existing "main", and ENV vars are being
passed along as well. The one big remaining complication I don't have an
answer for just yet is OS signals; they get registered only in the
server process, so signals from the client don't propagate through. It's
fixable of course, by having the client register and the server just
listen for client signal events, but that isn't supported in the current
NG. So there's some work to do.

All the NG stuff is in JRuby trunk right now. Give it a shot. I'm
interested in hearing opinions on it.

- Charlie
Roger Pack
2007-11-09 23:55:16 UTC
Permalink
Post by Roger Pack
Wow it would appear that jruby is indeed faster, and indeed uses a lot
more memory :) (or maybe that's just startup overhead). thanks for a
good program!
I wonder if jruby uses reference counting for its ruby objects (or if it
even matters), and if not maybe someday it would :) I'm just in a pro
reference counting mood these days :)

-Roge
--
Posted via http://www.ruby-forum.com/.
Rick DeNatale
2007-11-10 13:38:38 UTC
Permalink
Post by Roger Pack
Post by Roger Pack
Wow it would appear that jruby is indeed faster, and indeed uses a lot
more memory :) (or maybe that's just startup overhead). thanks for a
good program!
I wonder if jruby uses reference counting for its ruby objects (or if it
even matters), and if not maybe someday it would :) I'm just in a pro
reference counting mood these days :)
I very much doubt it.

Roger, you REALLY need to read the literature on GC which has been
accumulating for the past 50 years.

Reference counting is pretty much an obsolete approach to GC. It was
probably the first approach taken for lisp back in the 1950s. Other
language implementations usually started with reference counting (e.g.
the first Smalltalk).

It's main advantage is that it's easy to understand. On the other hand
it incurs a large overhead since counts need to be
incremented/decremented on every assignment. It can't detect circular
lists of dead objects. In early Smalltalk programs when reference
counting was used, you needed to explicitly nil out references to
break such chains. There's also the issue of the overhead for storing
the reference count, and how many bits to allocate. Most reference
counting implementations punt when the reference count overflows, they
treat a 'full' count as an infinite count and no longer decrement it,
leading to more uncollectable objects.

Mark and sweep, such as is used in the Ruby 1.8 implementation quickly
replaced reference counting as the simplest GC considered for real
use.

More modern GCs tend to use copying GCs which move live objects to new
heap blocks leaving the dead ones behind. And most use generational
scavenging which takes advantage of the observation that most objects
either die quite young, or live a long time. This approach was
pioneered by David Ungar in the Berkeley implementation of
Smalltalk-80. And this is the kind of GC typically used in JVMs
today.

Which particular GC approach is best for Ruby is subject to some study.

Many of the usages of ruby aren't quite like those of Java, or
Smalltalk. I had dinner with a former colleague, who happens to be
the lead developer of the IBM J9 java virtual machine, and he made the
observation that Java, and Smalltalk before it have a long history of
having their VMs tuned for long running processes. On the other hand
many Ruby usages are get in and get out. These use cases mean that
it's more valuable to have rapid startup than perfect GC in the sense
that all dead objects are reclaimed quickly, not that any of the
current GCs guarantee the latter.

So the best GC for Ruby might not be the same as would be used for a
JVM or Smalltalk VM, but I'm almost certain it would be a reference
counter.
--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/
joey eisma
2007-11-07 21:01:08 UTC
Permalink
Note: parts of this message were removed by the gateway to make it a legal Usenet post.

thx everyone for the reply. for the fine examples (some i don't quite understand yet..) as i'm still in the very early stages yet..

can i assume that it's simplier to use . than :: for references to methods?

thanks!


----- Original Message ----
From: Alex Young <***@blackkettle.org>
To: ruby-talk ML <ruby-***@ruby-lang.org>
Sent: Wednesday, November 7, 2007 10:13:01 AM
Subject: Re: :: and .
hi!
reading through some tutorial, i noticed the author would interchange using :: and . to call methods. i see they both give the same result.
i was wondering if there is any other difference between the two? (other than convenience maybe?). when would you use one over the other?
In addition to the other answers, there's one place that you can only
use '::' rather than '.', and that's when you're specifying that your
constant should be searched for in the root namespace:

Bar = 42
module Foo
Bar = 23
def Foo.show
p ::Bar
p Bar
end
end

Foo.show outputs:
42
23
--
Alex

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Jesse Edelstein
2007-11-07 22:46:41 UTC
Permalink
Post by joey eisma
thx everyone for the reply. for the fine examples (some i don't quite understand yet..) as i'm still in the very early stages yet..
can i assume that it's simplier to use . than :: for references to methods?
thanks!
Yep. Seems like bad form to me to use :: for no real reason.
Continue reading on narkive:
Loading...