[#362083] Teaching Programming Languages (including Ruby) — Samuel Williams <space.ship.traveller@...>

Hello,

20 messages 2010/05/02

[#362098] Main working window for Ruby is DOS? — Kaye Ng <sbstn26@...>

I know nothing about programming and am not a techy person, so please

16 messages 2010/05/03

[#362116] School teacher still at it learning programming language — Hilary Bailey <my77elephants@...>

Now I while glimpsing at the beauty of Ruby, there is the software of

11 messages 2010/05/03

[#362166] Something I expected to work, but didn't! — Kurtis Rainbolt-greene <kurtisrainboltgreene@...>

irb(main):001:0> x = 2

11 messages 2010/05/04

[#362215] for-in vs. map closures — Mike Austin <mike_ekim@...>

I was experimenting with closures and JavaScript's and Ruby's

11 messages 2010/05/05

[#362286] ri on sqlite — Intransition <transfire@...>

What do others think of a creating a new ri tool which uses a SQLite

17 messages 2010/05/06

[#362341] ease of porting (translating) ruby to C (vs. python)? — bwv549 <jtprince@...>

In a very small bioinformatics group I know of, they are deciding

17 messages 2010/05/07

[#362375] Strings iteration — Viorel <viorelvladu@...>

I have some names like aaxxbbyy where xx is '01'..'10' and yy is also

14 messages 2010/05/08

[#362425] Any future for curses applications/toolkits like rbcurse ? — "R. Kumar" <sentinel.2001@...>

Have apps moved over to the web (or GUI) totally ? Will there be any

21 messages 2010/05/10
[#362441] Re: Any future for curses applications/toolkits like rbcurse ? — botp <botpena@...> 2010/05/10

On Mon, May 10, 2010 at 2:13 PM, R. Kumar <sentinel.2001@gmx.com> wrote:

[#362448] Re: Any future for curses applications/toolkits like rbcurse ? — "R. Kumar" <sentinel.2001@...> 2010/05/10

interface and/or the installation itself is terrible.

[#362458] Re: Any future for curses applications/toolkits like rbcurse ? — botp <botpena@...> 2010/05/10

On Mon, May 10, 2010 at 10:28 PM, R. Kumar <sentinel.2001@gmx.com> wrote:

[#362460] Re: Any future for curses applications/toolkits like rbcurse ? — "R. Kumar" <sentinel.2001@...> 2010/05/10

botp wrote:

[#362463] Re: Any future for curses applications/toolkits like rbcurse ? — "R. Kumar" <sentinel.2001@...> 2010/05/10

Strange. I cant push a gem even after yanking.

[#362452] Unit Test of method calling system() - how? — Martin Hansen <mail@...>

How can I unit test the two methods:

16 messages 2010/05/10

[#362498] In Ruby, can the coerce() method know what operator it is th — Jian Lin <blueskybreeze@...>

In Ruby, it seems that a lot of coerce() help can be done by

12 messages 2010/05/11
[#362546] Re: In Ruby, can the coerce() method know what operator it is th — Caleb Clausen <vikkous@...> 2010/05/11

On 5/10/10, Jian Lin <blueskybreeze@gmail.com> wrote:

[#362611] Re: In Ruby, can the coerce() method know what operator it is th — Colin Bartlett <colinb2r@...> 2010/05/12

On Tue, May 11, 2010 at 4:46 PM, Caleb Clausen <vikkous@gmail.com> wrote:

[#362657] Asynchronous HTTP request — Daniel DeLorme <dan-ml@...42.com>

Does anyone know how to do the following, but without threads, purely

28 messages 2010/05/13

[#362718] Range on strings. — Vikrant Chaudhary <nasa42@...>

Hi,

13 messages 2010/05/14

[#362787] class best way for getters ? — unbewusst.sein@... (Une B騅ue)

i have a class "HFSFile" initialized by a parsed string

12 messages 2010/05/15

[#362979] curl library? — Xeno Campanoli / Eskimo North and Gmail <xeno.campanoli@...>

Two questions:

14 messages 2010/05/18
[#362980] Re: curl library? — Xeno Campanoli / Eskimo North and Gmail <xeno.campanoli@...> 2010/05/18

On 10-05-18 02:35 PM, Xeno Campanoli / Eskimo North and Gmail wrote:

[#362982] Re: curl library? — Luis Parravicini <lparravi@...> 2010/05/18

On Tue, May 18, 2010 at 6:56 PM, Xeno Campanoli / Eskimo North and

[#362984] Re: curl library? — Xeno Campanoli / Eskimo North and Gmail <xeno.campanoli@...> 2010/05/18

Well, I got that -dev thing installed with apt-get, and then I tried again and

[#363027] Retrieve instance — Walle Wallen <walle.sthlm@...>

Quick question. Can I somehow retrieve the instance of the class Test in

11 messages 2010/05/19

[#363076] Scrape javascript content — Phil Mcdonnell <phil.a.mcdonnell@...>

I'm trying to scrape a page that hides some data behind a javascript

11 messages 2010/05/20

[#363115] OMG, why are there so many Strings in ObjectSpace! — timr <timrandg@...>

I was playing around looking at ObjectSpace in irb and was astounded

14 messages 2010/05/21

[#363225] Redefine a Class? — Mark T <paradisaeidae@...>

Currently this raises: superclass mismatch for class Soda (TypeError)

12 messages 2010/05/25

[#363240] Funny IO.select behaviour — Dennis Nedry <dennis@...>

I've been debugging my full screen console ruby editor.

13 messages 2010/05/25

[#363348] Ruby as Client Side Language in Web Browser (replacing JS) — "Simone R." <k5mmx@...>

Hi everybody,

17 messages 2010/05/27

[#363412] A better way to write this function? — Jason Lillywhite <jason.lillywhite@...>

Here is my attempt at Newton's second law in Ruby:

14 messages 2010/05/28

[#363417] Interrupting the evaluation of a ruby script — Emmanuel Emmanuel <emmanuel.bacry@...>

This is my problem :

12 messages 2010/05/28
[#363447] Re: Interrupting the evaluation of a ruby script — Branden Tanga <branden.tanga@...> 2010/05/28

Emmanuel Emmanuel wrote:

[#363483] Re: Interrupting the evaluation of a ruby script — Emmanuel Emmanuel <emmanuel.bacry@...> 2010/05/29

[#363426] A complete beginners question — Ant Walliams <anthonywainwright@...>

Hi there,

19 messages 2010/05/28

[#363432] Dynamic SVG with Ruby/Tk — Yotta Meter <spam@...>

The example I'm looking for in regards to ruby/SVG differs from the

14 messages 2010/05/28

[#363467] Date.today problem on linux with Ruby 1.8.6 — Jarmo Pertman <jarmo.p@...>

Hello.

10 messages 2010/05/29

[#363524] enumerator problem in 1.9.1 — Bug Free <amberarrow@...>

The following line:

19 messages 2010/05/31
[#363528] Re: enumerator problem in 1.9.1 — botp <botpena@...> 2010/05/31

On Mon, May 31, 2010 at 9:04 AM, Bug Free <amberarrow@yahoo.com> wrote:

[#363533] Re: enumerator problem in 1.9.1 — Robert Klemme <shortcutter@...> 2010/05/31

2010/5/31 botp <botpena@gmail.com>:

Re: iterating over sub arrays

From: David Masover <ninja@...>
Date: 2010-05-17 18:44:17 UTC
List: ruby-talk #362889
On Sunday, May 16, 2010 07:49:56 pm James Harrison wrote:
> > Anyway, seems like one obvious way would be recursion:
> > 
> > def each_join array, context=[], &block
> > 
> >  if array.length == 0
> >  
> >    yield context
> >  
> >  else
> >  
> >    first = array.first
> >    rest = array[1...array.length]
> >    first.each do |elem|
> >    
> >      each_join rest, context+[elem], &block
> >    
> >    end
> >  
> >  end
> > 
> > end
> > 
> > Not pretty, and I'm sure someone could improve it, but it works.
> 
> That it does, that it does. Unfortunately, I don't understand it. If you've
> got a minute, would you give a hand?
> 
> It looks to me like:
> 
> each_join takes three arguments. The first is an array, the second is
> predefined to be an empty array, the third is a reference to a block.

The second is _defaulted_ to be an empty array. You can override it -- and the 
idea is not for you to override it, but for me to when I call that method 
recursively.

> A Proc object lets you assign a block to a variable. My naive reading of
> http://ruby-doc.org/core/classes/Proc.html leads me to imagine that the
> first benefit of this is that you can assign what's essentially a method
> call to a variable, almost like you're making a new object out of the
> variable. What does the object do? Take some number of arguments to its
> call method, and do something with those arguments.
> 
> Why would you want to use this? I don't know. But it looks like that's all
> it does.

Well, one example would be something like Rake. I can specify a task like 
this:

task :foo do
  # stuff
end

Rake will then take my block and store it in some data structure, as part of a 
Task object, which tracks its dependencies and everything else. When it's time 
to actually run that code, it digs it up and calls it.

It's really quite useful, but you should avoid it when possible -- use yield 
and block_given? instead -- because it's slightly more expensive to actually 
convert it to a proc object.

> And what does this have to do with each_join?

Because the outer call to each_join never calls 'yield'. What it's doing is 
taking that same block and passing it to the inner calls, so that eventually, 
when you get to that first part of the 'if' statement (if the array is empty, 
which I should've written as 'if array.empty?'), it will be calling the same 
block you passed in in the first place.

> Okay. The second argument, context. I'm not sure what it's doing. It's an
> empty array which is handed back to the block when the length of the
> original argument array is zero. I don't see how the argument array ever
> gets set to zero, though.

Let's step through it:

Basically, I'm using the Lisp idea of dealing with the first element, and then 
the rest of the array. So, look here:

first = array.first
rest = array[1...array.length]

So, if your array was [1, 2, 3],
first is 1
rest is [2, 3]

Then, look at the actual recursive call:

each_join rest, context+[elem], &block

So here, I'm calling each_join with 'array' set to 'rest', and I'm also adding 
an element from 'first' to the context. So the first call to each_join has 
array as [1, 2, 3]. As it gets deeper, you get a call of [2, 3], then one with 
[3], then one with []. At each step, it's adding the current element of first 
(from that loop) to the context.

> Okay, here goes my explanation:
> 
> Why is &block passed in? So that on successive calls to each_join, the
> block is correctly associated with the method.

Not "successive", but recursive.

> At the if statement, array.length is non-zero. As such, we go to the else
> clause. The first sub-array is assigned to the variable "first". The other
> subarrays are assigned to the variable "rest". So in the case of an array
> of arrays:
> [["bacon", "time", "ostrich"], ["jam", "bees", "please"], ["1", "2", "3"]]
> 
> After the first pass:
> 
> first = ["bacon", "time", "ostrich"]
> rest = [["jam", "bees", "please"], ["1", "2", "3"]]
> 
> And then you start iterating over first.
> 
> first.each do |elem| #first time around, elem == "bacon"
> each_join rest, context+[elem], &block
> 
> So what happens now?
> 
> first = ["jam", "bees", "please"]
> rest = ["1", "2", "3"]

And, here's the important point, for the first iteration,

context = ["bacon"].

Then, after that entire inner loops finish, you get called again, like this:

context = ["time"]
first = ["jam", "bees", "please"]
rest = ["1", "2", "3"]

And so on.

Let's follow it to an inner iteration:

context = ["bacon", "jam"]
first = ["1", "2", "3"]
rest = []

And finally, to the place you actually yield:

context = ["bacon", "jam", "1"]
array = []

I don't know if that makes more sense -- you probably saw most of this with 
your trace.

> > It does seem pretty weird, though. Out of curiosity, what do you need
> > this for?
> 
> Okay, you gave me quite an education today, so turn about is fair play.
> 
> I have a program which accepts input and outputs output.
> It has both a gui and a scripting environment.
[snip]
> Each option can only be specified once, but each option can have
> multiple valid values. In order to verify that every option that can be
> handed in actually works as expected, I want to generate a set of scripts
> from the documentation I wrote. The parser I have for the documentation
> finds a series of lines of type:
> 
> foo=bar -- does something fooish
> foo=bam -- does something else fooish
> 
> jet=bar -- does something jetish
> jet=bam -- does something else jetish
> 
> and so on. I'm popping each option string into an array:
> 
> [[foo=bar, foo=bam], [jet=bar, jet=bam]]
> 
> And from there, generate every possible combination of all options. I'd
> done everything else, but that last item on the list was killin' me.

Are all of them required, though? Because that's the assumption I was working 
with. One way to avoid that might be to add an iteration to each of these 
where you _don't_ add that item. That is, change the inner loop to:


first.each do |elem|
  each_join rest, context+[elem], &block
end
# call again, without _anything_ from this array
each_join rest, context, &block

And if you really want to balloon the number of test cases, you could make 
sure it works in any order. That is, when you use this:

each_join(array_collection) do |options|
  options.permutation.each do |perm|
    # do something with each permutation
  end
end

Also, as a mental exercise, you could try re-implementing this without 
recursion. I wouldn't do that unless you actually start having thousands of 
items, though -- I would hope you won't run into stack overflows, because that 
would be an insane number of iterations!



Ok, I thought I'd be done, but this is just bothering me. I'm going to make it 
prettier:

class Array
  def each_join
    return enum_for(:each_join) unless block_given?

    if empty?
      yield []
    else
      array.first.each do |elem|
        first = [elem]
        array[1...array.length].each_join do |subarray|
          yield first + subarray
        end
      end
    end
  end
end

I think that still does the same thing. It's probably less efficient, but I'm 
really not sure. It might be a little easier to understand, though.

In This Thread

Prev Next