[#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
[#324442] Re: Pure Ruby Zlib::GzipWriter — Luis Lavena <luislavena@...> 2009/01/10

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

[#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

[#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  
more difficult that it appears. (Or, perhaps, y'all are busy preparing  
for the holidays.) The sole submission for this quiz comes from  
_Robert Dober_; it's not completely to specification nor handles the  
bonus, but it is a good start. (More appropriately, it might be better  
to say that the specification isn't entirely clear, and that Robert's  
implementation didn't match *my* interpretation of the spec; a proper  
`ANSIString` module would need to provide more details on a number of  
things.)

Robert relies on other libraries to provide the actual ANSI codes;  
seeing as there are at least three libraries that do, Robert provides  
a mechanism to choose between them based on user request and/or  
availability. Let's take a quick look at this mechanism. (Since this  
quiz doesn't use the Module mechanism in Robert's `register_lib`  
routine, I've removed the related references for clarity. I suspect  
those are for a larger set of library management routines.)

	@use_lib =
	  ( ARGV.first == '-f' || ARGV.first == '--force'  ) &&
	    ARGV[1]
	
     def register_lib lib_path, &blk
       return if @use_lib && lib_path != @use_lib
       require lib_path
       Libraries[ lib_path ] = 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 = Libraries.keys[ rand( Libraries.keys.size ) ]
	  lib = Libraries[ used_lib_name ]
	  case lib
	  when Proc
	    define_method :__color__, &lib
	  else
	    raise RuntimeError, "Nooooo I have explained exactly how to  
register libraries, has I not?"
	  end

	  # ... rest of ANSIString ...
	end
	
First, we check if the user has requested (via `--force`) a particular  
library. This is used in the first line of `register_lib`, which exits  
early if we try to register a library other than the one specified.  
Then `register_lib` loads the matching library (or all if the user did  
not specify) via `require` as is typical. Finally, a reference to the  
provided code block is kept, indexed by the library name.

This seems, perhaps, part of a larger set of library management  
routines; its use in this quiz is rather simple, as can be seen in the  
calls to `register_lib` immediately following. While registering  
"facets/ansicode", a block is provided to call `ANSICode.send color`.  
This is then used below in `ANSIString`, when we choose one of the  
libraries to use, recall the corresponding code block, and define a  
new method `__color__` that calls that code block.

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

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

	class ANSIString
	  ANSIEnd    = "\e[0m"

	  def initialize *strings
	    @strings = 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
	
Internally, `ANSIString` keeps an array of strings, its initial value  
set to a copy of the initialization parameters. So we can create ANSI  
string objects in a couple of ways:

	s1 = ANSIString.new "Hello, world!"
	s2 = ANSIString.new :green, "Merry ", :red, "Christmas!", :end
	
When converting with `to_s`, each member of that array is  
appropriately converted to a `String`. It is assumed that members of  
the array are either already `String` objects (so are mapped to  
themselves), the `:end` symbol (so mapped to constant string  
`ANSIEnd`), or appropriate color symbols available in the previously  
loaded library (mapped to the corresponding ANSI string available  
through method `__color__`). Once all items in the array are converted  
to strings, a simple call to `join` binds them together into one,  
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 === x} == :end ?
	      @strings.dup : @strings.dup << :end
	  end
	end

Before we get to the concatenation itself, take a quick look at helper  
method `__end__`. It looks for the last symbol and compares it against  
`:end`. Whether true or false, the `@string` array is duplicated (and  
so protects the instance variable from change). Only, `__end__` does  
not append another `:end` symbol if unnecessary.

I was a little confused, at first, about the implementation of  
`ANSIString` concatenation. Perhaps Robert had other plans in mind,  
but it seemed to me this work could be simplified. Since `add_reverse`  
is called nowhere else (and I couldn't imagine it being called by the  
user, despite the public interface), I tried inserting `add_reverse`  
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  
second case, until I realized my mistake: `other` is not necessarily  
of the `ANSIString` class, and so would not have the `__end__` method.  
My attempt to fix my mistake was to rewrite again as this:

	def + other
	  ANSIString::new( *( __end__ + other.to_s ) )
	end
	
But that has its own problems if `other` *is* an `ANSIString`; it  
neglects to end the string and converts it to a simple `String` rather  
than maintaining its components. Clearly undesirable. Obviously,  
Robert's implementation is the right way... or is it? Going back to  
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  
throw the `NoMethodError` exception, because `String` does not define  
`__end__`, just as Robert's version throws that exception if either  
`add_reverse` or `__end__` is not defined. So, removing redundancy, I  
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  
understandable.

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

Finally, we deal with adding ANSI codes to the ANSI strings (aside  
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
	
Method `end` simply appends the symbol `:end` to the `@strings` array  
by making use of the existing `__end__` method. Reusing `__end__` (as  
opposed to just doing `@strings << :end`) ensures that we don't have  
unnecessary `:end` symbols in the string.

Finally, `method_missing` catches all other calls, such as `bold` or  
`red`. Any calls with arguments or a code block are passed up first to  
the superclass, though considering the parent class is `Object`, any  
such call is likely to generate a `NoMethodError` exception (since, if  
the method was in `Object`, `method_missing` would not have been  
called). Also note that whether "handled" by the superclass or not,  
all missing methods are *also* handled by the rest of the code in  
`method_missing`. I don't know if that is intentional or accidental.  
In general, this seems prone to error, and it would seem a better  
tactic either to discern the ANSI code methods from the loaded module  
or to be explicit about such codes.

In any case, calling `red` on `ANSIString` the first time actually  
generates a new method, by way of the `define_method` call located in  
`method_missing`. Further calls to `red` (and the first call, via the  
last line `send name`) will actually use that new method, which  
prepends `red.to_sym` (that is, `:red`) to the string in question.

At this point, `ANSIString` handles basic initialization,  
concatenation, ANSI codes and output; it does not handle the rest of  
the capabilities of `String` (such as substrings, `gsub`, and others),  
so it is not a drop-in replacement for strings. I believe it could be,  
with time and effort, but that is certainly a greater challenge than  
is usually attempted on Ruby Quiz.


In This Thread