Topic: Turning blocks into arrays

Simple problem I am trying to solve. I am often given a list of links which are conditionally output and concatenated with pipe characters.

Example:

Link 1 | Link 2 | Link 3

My aim is to write a method which would allow me to achieve this as follows:


- split_links do
  - if foo?
    = link_to "foo", "#foo"
  - if bar?
    = link_to "bar", "#bar"
  = link_to "baz", "#baz"

  # only foo? is true
  => Foo | Baz

I know I can capture a block within a helper, but i have no idea how to append each argument to an array that I can manipulate with join(' | ')

Any ideas?

Last edited by pimpmaster (2011-06-23 08:06:13)

Re: Turning blocks into arrays

If I got you right, you can use 'collect' method:

a = [ "a", "b", "c", "d" ]
a.collect {|x| x + "|" }   #=> ["a|", "b|", "c|", "d|"]

Last edited by Javix (2011-06-23 09:54:32)

Re: Turning blocks into arrays

If it was a simple array I was dealing with this would be a snap with join()

['my','cool','array'].join(' | ')

=> "my | cool | array"

Unfortunately, due to the conditional nature of the links, using an array gets a bit messy:

[(link_to('foo','#foo') if foo?), (link_to('bar','#bar') if bar?), (link_to('baz','#baz') if baz?)].join(' | ')

Which is why I am trying to do this using block syntax instead
 

- split_links do
  - if foo?
    = link_to 'foo', '#foo'
  # etc

Last edited by pimpmaster (2011-06-23 10:25:38)

Re: Turning blocks into arrays

What does split_links look like in 'real life'?

Two options spring to mind, but with seeing what the actual data looks like they might not be useful smile

1. Build the array first, then join it, e.g

links = []
links << link_to("foo", "#foo") if foo?
links << link_to("bar", "#bar") if bar?
links << link_to("baz", "#baz") if baz?
links.join("|")

2. use inject/each_with_object on split_links

which is why i asked what it looks like big_smile

Rob Anderton
TheWebFellas

Re: Turning blocks into arrays

@rob-twf

Option #1 is what I am using right now given I can't get my block syntax working

The split_links method doesn't loo like anything. The farthest I got was poking around at the Proc object and dealing with all sorts of weirdness (like block.call returning an integer.. wtf??)

Option # 2 looks compelling. Care to expand on that?

Re: Turning blocks into arrays

Let's say split_links = [ "foo", "bar", "baz" ]

and a link should be created unless a '?' method matching the name of a link exists that when called returns false

you could then do something like this:

split_links.each_with_object([]) do |link, html|
  html << link_to(link, "##{link}") unless respond_to?("#{link}?") && !send("#{link}?")
end.join("|")

Probably won't work without some tweakage - as it'll depend on where this code lives for whether the respond_to? and send stuff works, but should give you something to play with.... unless I've gone off at completely the wrong tangent big_smile

Rob Anderton
TheWebFellas