[#321574] Regular Expressions — Mmcolli00 Mom <mmc_collins@...>

Hi everyone.

15 messages 2008/12/01

[#321655] Ruby cgi script — ZippySwish <fischer.jan@...>

I put "script.rb" into the cgi-bin folder of my webhost, but nothing's

12 messages 2008/12/02

[#321733] FFI 0.2.0 — "Wayne Meissner" <wmeissner@...>

Greetings Rubyists.

20 messages 2008/12/03

[#321920] Force a program to stop if runtime exceeds given duration — Aldric Giacomoni <"aldric[remove]"@...>

Any idea how to do that?

25 messages 2008/12/04
[#321924] Re: Force a program to stop if runtime exceeds given duration — "Glen Holcomb" <damnbigman@...> 2008/12/04

On Thu, Dec 4, 2008 at 10:04 AM, Aldric Giacomoni <"aldric[remove]"@

[#322011] Re: Force a program to stop if runtime exceeds given duration — Ron Fox <fox@...> 2008/12/05

See http://www.ruby-doc.org/core-1.9/classes/Process.html#M003012

[#322016] Re: Force a program to stop if runtime exceeds given duration — Aldric Giacomoni <"aldric[remove]"@...> 2008/12/05

Everybody automatically assumes that rubyists are using Linux - sadly,

[#321969] Are there any Ruby Technical Writers here? — Vito Fontaine <vito.matro@...>

I am a beginner with Ruby who was interested in writing some programs.

15 messages 2008/12/04
[#321975] Re: Are there any Ruby Technical Writers here? — Robert Klemme <shortcutter@...> 2008/12/04

On 04.12.2008 22:43, Vito Fontaine wrote:

[#321984] Re: Are there any Ruby Technical Writers here? — Vito Fontaine <vito.matro@...> 2008/12/05

Robert Klemme wrote:

[#322014] Proximity searches in Ruby — Stuart Clarke <stuart.clarke1986@...>

Does Ruby have the ability to perform proximity searches on data. For

14 messages 2008/12/05
[#322056] Re: Proximity searches in Ruby — Ilan Berci <coder68@...> 2008/12/05

No proximity searches with 1.8.. you would need a full fledged text

[#322073] shoes 2 (raisins) is go. — _why <why@...>

Salutations and hi.

13 messages 2008/12/06

[#322260] Help on algorythm — Helder Oliveira <hrpoliveira@...>

Guys i have been trying to make this algorythm but with no sucess, can

13 messages 2008/12/09
[#322261] Re: Help on algorythm — "Glen Holcomb" <damnbigman@...> 2008/12/09

On Tue, Dec 9, 2008 at 7:44 AM, Helder Oliveira <hrpoliveira@gmail.com>wrote:

[#322283] Completely new programmer lacks direction — Cameron Carroll <ubernoobs@...>

Hi. I recently picked up a beginning ruby book, having only lightly

17 messages 2008/12/09

[#322285] compare 2 text files - check for difference - Please help — Mmcolli00 Mom <mmc_collins@...>

Hi. I want to take two files that are supposed to be identical, then ook

12 messages 2008/12/09
[#322301] Re: compare 2 text files - check for difference - Please help — Brian Candler <b.candler@...> 2008/12/09

Mmcolli00 Mom wrote:

[#322306] Re: compare 2 text files - check for difference - Please help — Mmcolli00 Mom <mmc_collins@...> 2008/12/09

require 'diff/lcs/Array'

[#322417] why Hash corrupts 'key' object ? — Dmitry Perfilyev <dmitry1976@...>

Hi, I have next script:

13 messages 2008/12/10

[#322464] Q: FFI and C++? — Jeremy Henty <onepoint@...>

If I want to wrap a C++ library using FFI, can it cope with the name

14 messages 2008/12/11

[#322516] Invoking Ruby code from a low-level language? — Alex Fulton <a.fulton@...>

Hi, my sincerest apologies if this question has already been answered

11 messages 2008/12/11

[#322529] parallel method return value — Louis-Philippe <default@...>

Hi all,

17 messages 2008/12/12

[#322566] How to run background processes (more than 1 worker) parallely. — "Deepak Gole" <deepak.gole8@...>

Hi

10 messages 2008/12/12

[#322624] singleton methods vs. meta instance methods — Daniel DeLorme <dan-ml@...42.com>

If I understand the ruby object model correctly, then an object's

15 messages 2008/12/13

[#322705] ruby 1.9.1: Encoding trouble: broken US-ASCII String — Tom Link <micathom@...>

Hi,

22 messages 2008/12/14

[#322710] Help with an "easy" regular expression substitution — Iñaki Baz Castillo <ibc@...>

Hi, I'm getting crazy to get a theorically easy substitution:

16 messages 2008/12/14

[#322819] Pure Ruby Zlib::GzipWriter — Daniel Berger <djberg96@...>

Hi,

53 messages 2008/12/15
[#323877] Re: Pure Ruby Zlib::GzipWriter — Daniel Berger <djberg96@...> 2009/01/03

[#323903] Re: Pure Ruby Zlib::GzipWriter — Roger Pack <rogerpack2005@...> 2009/01/04

[#324011] Re: Pure Ruby Zlib::GzipWriter — Daniel Berger <djberg96@...> 2009/01/05

[#324442] Re: Pure Ruby Zlib::GzipWriter — Luis Lavena <luislavena@...> 2009/01/10

On Jan 9, 9:26=A0pm, "Charles L." <aquas...@gmail.com> wrote:

[#322987] Using ruby hash on array — Stuart Clarke <stuart.clarke1986@...>

I would like to process some data from an array and using hash to

14 messages 2008/12/17

[#323085] Ruby and Rails supported on 10gen — "Jim Menard" <jim.menard@...>

http://www.10gen.com/blog/2008/12/ruby-support-on-10gen

11 messages 2008/12/18

[#323166] Dreaming of a Ruby Christmas (#187) — Matthew Moss <matt@...>

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

11 messages 2008/12/19

[#323204] get first and last line from txt file - how? — Mmcolli00 Mom <mmc_collins@...>

I have txt file with date/time stamps only. I want to grab the first

19 messages 2008/12/20
[#323205] Re: get first and last line from txt file - how? — Tim Hunter <TimHunter@...> 2008/12/20

Mmcolli00 Mom wrote:

[#323207] Re: get first and last line from txt file - how? — "Yaser Sulaiman" <yaserbuntu@...> 2008/12/20

I'm just wondering..

[#323273] how to make installing Ruby easier for amateurs — Tom Cloyd <tomcloyd@...>

Greetings!

21 messages 2008/12/22

[#323312] Name that data structure! — Simon Chiang <simon.a.chiang@...>

I'm using a data structure that I'm sure has been implemented and

18 messages 2008/12/22
[#323314] Re: Name that data structure! — "Gregory Brown" <gregory.t.brown@...> 2008/12/22

On Mon, Dec 22, 2008 at 5:38 PM, Simon Chiang <simon.a.chiang@gmail.com> wrote:

[#323342] Are all Ruby built-in objects thread safe? — "Just Another Victim of the Ambient Morality" <ihatespam@...>

Are all built-in objects thread safe? For example, if I have an array

23 messages 2008/12/23
[#323346] Re: Are all Ruby built-in objects thread safe? — Yukihiro Matsumoto <matz@...> 2008/12/23

Hi,

[#323519] What does 'Monkey Patching' exactly Mean in Ruby? — "Yaser Sulaiman" <yaserbuntu@...>

According to Wikipedia, a monkey patch[1] is:

36 messages 2008/12/27
[#323813] Re: What does 'Monkey Patching' exactly Mean in Ruby? — Jg W Mittag <JoergWMittag+Usenet@...> 2009/01/02

Phlip wrote:

[#323832] Re: What does 'Monkey Patching' exactly Mean in Ruby? — "David A. Black" <dblack@...> 2009/01/02

Hi --

[#323644] Why Ruby? — Mike Stephens <rubfor@...>

I have never seen or heard of Ruby in a corporate context. The single

35 messages 2008/12/30

[#323668] Ruby 1.9.1 RC1 is released — "Yugui (Yuki Sonoda)" <yugui@...>

Hi, folks

21 messages 2008/12/30

[SUMMARY] AnsiString (#185)

From: Matthew Moss <matt@...>
Date: 2008-12-12 18:06:06 UTC
List: ruby-talk #322583
It would seem that writing Transfire's desired `ANSIString` class is =20
more difficult that it appears. (Or, perhaps, y'all are busy preparing =20=

for the holidays.) The sole submission for this quiz comes from =20
_Robert Dober_; it's not completely to specification nor handles the =20
bonus, but it is a good start. (More appropriately, it might be better =20=

to say that the specification isn't entirely clear, and that Robert's =20=

implementation didn't match *my* interpretation of the spec; a proper =20=

`ANSIString` module would need to provide more details on a number of =20=

things.)

Robert relies on other libraries to provide the actual ANSI codes; =20
seeing as there are at least three libraries that do, Robert provides =20=

a mechanism to choose between them based on user request and/or =20
availability. Let's take a quick look at this mechanism. (Since this =20
quiz doesn't use the Module mechanism in Robert's `register_lib` =20
routine, I've removed the related references for clarity. I suspect =20
those are for a larger set of library management routines.)

	@use_lib =3D
	  ( ARGV.first =3D=3D '-f' || ARGV.first =3D=3D '--force'  ) &&
	    ARGV[1]
=09
     def register_lib lib_path, &blk
       return if @use_lib && lib_path !=3D @use_lib
       require lib_path
       Libraries[ lib_path ] =3D blk
     end

     register_lib "facets/ansicode" do | color |
       ANSICode.send color
     end

	# similar register_lib calls for "highline" and "term/ansicolor"

	class ANSIString
	  used_lib_name =3D Libraries.keys[ rand( Libraries.keys.size ) =
]
	  lib =3D Libraries[ used_lib_name ]
	  case lib
	  when Proc
	    define_method :__color__, &lib
	  else
	    raise RuntimeError, "Nooooo I have explained exactly how to =20=

register libraries, has I not?"
	  end

	  # ... rest of ANSIString ...
	end
=09
First, we check if the user has requested (via `--force`) a particular =20=

library. This is used in the first line of `register_lib`, which exits =20=

early if we try to register a library other than the one specified. =20
Then `register_lib` loads the matching library (or all if the user did =20=

not specify) via `require` as is typical. Finally, a reference to the =20=

provided code block is kept, indexed by the library name.

This seems, perhaps, part of a larger set of library management =20
routines; its use in this quiz is rather simple, as can be seen in the =20=

calls to `register_lib` immediately following. While registering =20
"facets/ansicode", a block is provided to call `ANSICode.send color`. =20=

This is then used below in `ANSIString`, when we choose one of the =20
libraries to use, recall the corresponding code block, and define a =20
new method `__color__` that calls that code block.

Altogether, this is a reasonable technique for putting a fa=E7ade around =
=20
similar functionality in different libraries and choosing between =20
available libraries, perhaps if one or another is not available. It =20
seems to me that such library management =96 at least the general =20
mechanisms =96 might be worthy of its own gem.

Given that we now have a way to access ANSI codes via =20
`ANSIString#__color__`, let's now move onto the code related to the =20
task, starting with initialization and conversion to `String`:

	class ANSIString
	  ANSIEnd    =3D "\e[0m"

	  def initialize *strings
	    @strings =3D strings.dup
	  end

	  def to_s
	    @strings.map do |s|
	      case s
		  when String
		    s
		  when :end
		    ANSIEnd
		  else
		    __color__ s
		  end
		end.join
       end
	end
=09
Internally, `ANSIString` keeps an array of strings, its initial value =20=

set to a copy of the initialization parameters. So we can create ANSI =20=

string objects in a couple of ways:

	s1 =3D ANSIString.new "Hello, world!"
	s2 =3D ANSIString.new :green, "Merry ", :red, "Christmas!", :end
=09
When converting with `to_s`, each member of that array is =20
appropriately converted to a `String`. It is assumed that members of =20
the array are either already `String` objects (so are mapped to =20
themselves), the `:end` symbol (so mapped to constant string =20
`ANSIEnd`), or appropriate color symbols available in the previously =20
loaded library (mapped to the corresponding ANSI string available =20
through method `__color__`). Once all items in the array are converted =20=

to strings, a simple call to `join` binds them together into one, =20
final string.

Let's look at string concatenation:

	class ANSIString
	  def + other
	    other.add_reverse self
	  rescue NoMethodError
	    self.class::new( *( __end__ << other ) )
	  end

	  def add_reverse an_ansi_str
	    self.class::new( *(
	      an_ansi_str.send( :__end__ ) + __end__
	    ) )
	  end

	  private
	  def __end__
	    @strings.reverse.find{ |x| Symbol =3D=3D=3D x} =3D=3D :end ?
	      @strings.dup : @strings.dup << :end
	  end
	end

Before we get to the concatenation itself, take a quick look at helper =20=

method `__end__`. It looks for the last symbol and compares it against =20=

`:end`. Whether true or false, the `@string` array is duplicated (and =20=

so protects the instance variable from change). Only, `__end__` does =20
not append another `:end` symbol if unnecessary.

I was a little confused, at first, about the implementation of =20
`ANSIString` concatenation. Perhaps Robert had other plans in mind, =20
but it seemed to me this work could be simplified. Since `add_reverse` =20=

is called nowhere else (and I couldn't imagine it being called by the =20=

user, despite the public interface), I tried inserting `add_reverse` =20
inline to `+` (fixing names along the way):

	def + other
       other.class::new( *(self.send(:__end__) + other.__end__) )
	rescue NoMethodError
	  self.class::new( *( __end__ << other ) )
	end

And, with further simplification:

	def + other
	  other.class::new( *( __end__ + other.send(:__end__) ) )
	rescue NoMethodError
	  self.class::new( *( __end__ << other ) )
	end

I believed Robert had a bug, neglecting to call `__end__` in the =20
second case, until I realized my mistake: `other` is not necessarily =20
of the `ANSIString` class, and so would not have the `__end__` method. =20=

My attempt to fix my mistake was to rewrite again as this:

	def + other
	  ANSIString::new( *( __end__ + other.to_s ) )
	end
=09
But that has its own problems if `other` *is* an `ANSIString`; it =20
neglects to end the string and converts it to a simple `String` rather =20=

than maintaining its components. Clearly undesirable. Obviously, =20
Robert's implementation is the right way... or is it? Going back to =20
this version:

	def + other
	  other.class::new( *( __end__ + other.send(:__end__) ) )
	rescue NoMethodError
	  self.class::new( *( __end__ << other ) )
	end

Ignoring the redundancy, this actually works. My simplification will =20
throw the `NoMethodError` exception, because `String` does not define =20=

`__end__`, just as Robert's version throws that exception if either =20
`add_reverse` or `__end__` is not defined. So, removing redundancy, I =20=

believe concatenation can be simplified correctly as:

	def + other
		self.class::new( *(
			__end__ + (other.send(:__end__) rescue [other] )
		) )
	end

For me, this reduces concatenation to something more quickly =20
understandable.

One last point on concatenation; Robert's version will create an =20
object of class `other.class` if that class has both methods =20
`add_reverse` and `__end__`, whereas my simplification does not. =20
However, it seems unlikely to me that any class other than =20
`ANSIString` will have those methods. I recognize that my assumption =20
here may be flawed; Robert will have to provide further details on his =20=

reasoning or other uses of the code.

Finally, we deal with adding ANSI codes to the ANSI strings (aside =20
from at initialization):

	class ANSIString
	  def end
	    self.class::new( * __end__ )
	  end

	  def method_missing name, *args, &blk
	    super( name, *args, &blk ) unless args.empty? && blk.nil?
	    class << self; self end.module_eval do
	      define_method name do
	  		self.class::new( *([name.to_sym] + =
@strings).flatten )
	      end
	    end
	    send name
	  end
	end
=09
Method `end` simply appends the symbol `:end` to the `@strings` array =20=

by making use of the existing `__end__` method. Reusing `__end__` (as =20=

opposed to just doing `@strings << :end`) ensures that we don't have =20
unnecessary `:end` symbols in the string.

Finally, `method_missing` catches all other calls, such as `bold` or =20
`red`. Any calls with arguments or a code block are passed up first to =20=

the superclass, though considering the parent class is `Object`, any =20
such call is likely to generate a `NoMethodError` exception (since, if =20=

the method was in `Object`, `method_missing` would not have been =20
called). Also note that whether "handled" by the superclass or not, =20
all missing methods are *also* handled by the rest of the code in =20
`method_missing`. I don't know if that is intentional or accidental. =20
In general, this seems prone to error, and it would seem a better =20
tactic either to discern the ANSI code methods from the loaded module =20=

or to be explicit about such codes.

In any case, calling `red` on `ANSIString` the first time actually =20
generates a new method, by way of the `define_method` call located in =20=

`method_missing`. Further calls to `red` (and the first call, via the =20=

last line `send name`) will actually use that new method, which =20
prepends `red.to_sym` (that is, `:red`) to the string in question.

At this point, `ANSIString` handles basic initialization, =20
concatenation, ANSI codes and output; it does not handle the rest of =20
the capabilities of `String` (such as substrings, `gsub`, and others), =20=

so it is not a drop-in replacement for strings. I believe it could be, =20=

with time and effort, but that is certainly a greater challenge than =20
is usually attempted on Ruby Quiz.


In This Thread