I’m issuing this challenge because I’m
too lazy to do this myself.
Perhaps no one will be interested. But
I have a feeling someone could do this
with some trick I haven’t seen yet.
Problem: Given an input line consisting
of Ruby constants separated by whitespace,
return an array of those constants.
Hashes and arrays are allowed as long as
their contents are constants. Regexes are
allowed. Fancy strings are allowed, but
not here-docs. Proc objects and other
esoteric things are not allowed.
Have I left any holes in this problem? I’m
sure I have, and I’m sure the language
lawyers will be all over me.
Hashes and arrays are allowed as long as
their contents are constants. Regexes are
allowed. Fancy strings are allowed, but
not here-docs. Proc objects and other
esoteric things are not allowed.
I am thinking of this as a data format. So
there should be no variables used – nothing
that would require the presence or maintenance
of a certain context.
But what about something like #{rand} or
#{Time.now}? Truthfully I haven’t thought
about it.
Hal
···
----- Original Message -----
From: nobu.nokada@softhome.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Monday, February 24, 2003 1:15 AM
Subject: Re: Coding challenge: Space-separated constants
Hashes and arrays are allowed as long as
their contents are constants. Regexes are
allowed. Fancy strings are allowed, but
not here-docs. Proc objects and other
esoteric things are not allowed.
I based this on Joel Vanderwerf’s idea and made
the following adjustments.
I divide the whole string into “pieces” that
are each either whitespace or “blackspace”
I work a piece at a time instead of a char
at a time
I’ll bet this is faster, though I haven’t tried
a speed comparison.
I also added detection of malformed constants.
Code below. Improvement/critique welcome.
Hal
class String
def values
pieces = self.scan(/[ \t]+|[^ \t]+/)
vals =
str = “”
while pieces[0] do
piece = pieces.shift
str << piece
if str =~ /[1]+$/ # whitespace only
str = “”
next
end
begin
vals << eval(str)
str = “”
rescue Exception
if pieces[0]
next
else
raise “Bad value near #{str}”
end
end
end
vals
end
end
Hashes and arrays are allowed as long as
their contents are constants. Regexes are
allowed. Fancy strings are allowed, but
not here-docs. Proc objects and other
esoteric things are not allowed.
What about #{}?
Good question. My hesitant response is no.
I am thinking of this as a data format. So
there should be no variables used – nothing
that would require the presence or maintenance
of a certain context.
But what about something like #{rand} or
#{Time.now}? Truthfully I haven’t thought
about it.
Presumably they would be inside quotation marks:
str = ‘123 4.5 “#{rand}” “and so on”’
so if your solution is eval-based, the interpolation should just sort
of happen.
Simplified scan, moved error check outside loop, added eval binding
context, and wrote a haiku.
class String
def values (bind=nil)
res =
str = ‘’
scan(/\S+\s*/).each { |tok|
begin
res << eval(str << tok, bind)
str = ‘’
rescue Exception
end
}
str.empty? or raise “Bad value near: #{str}”
res
end
end
a = “I n c r e m e n t a l”
a = <<EOF.values binding
111 proc do |x| x.to_i.chr end <<-1
82
117 Refactoring code
98 Insert seven syllables
121 One line at a time
1
33 callcc {|x| x} print(a[0].chr,a[-2,2])
EOF
a.size < a[0] and a[4].call or puts “ve #{a[2].map(&a[1])}” << a[3]
Surely. As long as illegal things such as
“#{undefinedvar}” are caught and handled
appropriately. Whatever that means.
Hal
···
----- Original Message -----
From: dblack@candle.superlink.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Monday, February 24, 2003 8:48 AM
Subject: Re: Coding challenge: Space-separated constants
What about #{}?
Good question. My hesitant response is no.
I am thinking of this as a data format. So
there should be no variables used – nothing
that would require the presence or maintenance
of a certain context.
But what about something like #{rand} or
#{Time.now}? Truthfully I haven’t thought
about it.
Presumably they would be inside quotation marks:
str = ‘123 4.5 “#{rand}” “and so on”’
so if your solution is eval-based, the interpolation should just sort
of happen.
Simplified scan, moved error check outside loop, added eval binding
context, and wrote a haiku.
[snip code]
Worthy changes, thanks very much!
My favorite part is the haiku.
a = “I n c r e m e n t a l”
a = <<EOF.values binding
111 proc do |x| x.to_i.chr end <<-1
82
117 Refactoring code
98 Insert seven syllables
121 One line at a time
1
33 callcc {|x| x} print(a[0].chr,a[-2,2])
EOF
a.size < a[0] and a[4].call or puts “ve #{a[2].map(&a[1])}” << a[3]
For those who are too lazy to run this themselves,
the output is:
I looooooooooooooooooooooooooooooooooooooooooooooooooooove Ruby!
Thanks much for the refactoring and entertainment. The
code snippet above makes my brain itch.
I don’t recall seeing you post before… are you
a long-time lurker or have I just not been
paying attention?
Hal
···
----- Original Message -----
From: “Sabby and Tabby” sabbyxtabby@yahoo.com
Newsgroups: comp.lang.ruby
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Saturday, March 01, 2003 10:07 AM
Subject: Re: Coding challenge: Space-separated constants