403e57e2be130d2218f992b86dfa8260

With all the magic surrounding ruby I can't help but think that there are shorter and more readable ways to do this.

1
2
3
4
5
if self.location_type.to_s == 'point'
  breaker = self.lang == 'fr' ? 'proximite' : 'near'
 else  
  breaker = self.lang == 'fr' ? 'dans' : 'in'
end

Refactorings

No refactoring yet !

880cbab435f00197613c9cc2065b4f5a

danielharan

October 11, 2007, October 11, 2007 19:37, permalink

2 ratings. Login to rate!

Assuming you are only working with two languages...

1
2
3
4
5
if self.location_type.to_s == 'point'
  breaker = {'fr' => 'proximite', 'en' =>'near' }[self.lang]
else  
  breaker = {'fr' => 'dans',      'en' => 'in'  }[self.lang]
end
403e57e2be130d2218f992b86dfa8260

Gary Haran

October 11, 2007, October 11, 2007 19:55, permalink

1 rating. Login to rate!

in the middle of all of this I had to add another else... a coworker mentionned this example

1
2
3
4
5
6
7
8
9
p = Proc.new { |en, fr| lang.to_s == "en" ? en : fr }
breaker = case location_type
  when 'point'
    p.call('near', 'proximite')
  when 'street'
    p.call('on', 'sur')
  else
    p.call('in', 'dans')
end
Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

October 11, 2007, October 11, 2007 20:25, permalink

1 rating. Login to rate!

what about puting the localisation stuff in a yaml file ?

Yaml data file

1
2
3
4
5
6
7
8
9
point:
  en: near
  fr: proximite
street:
  en: on
  fr: sur
default:
  en: in
  fr: dans

Code

1
2
3
texts = File.open("path/to/text.yaml") { |file| YAML.load(file) }

breaker = (texts[location_type] || texts['default'])[lang.to_s]
B51ddb971f0e250f1cd68781f31b739b

Frahugo

October 12, 2007, October 12, 2007 01:13, permalink

No rating. Login to rate!

I'm using a Globalite plugin. I love it because it is a simple way to achieve what Marc-André just suggested. You install the plug-in, put your localized strings in Yaml files, set the current language in your controller and voila. You then the l() method on a symbol. The localized strings are read once and cached in memory (you havae to restart the server if you modify the files, but in production mode, we want that to avoid always reading files).

lang/ui/fr.yml

1
2
3
point: proximite
nopoint: dans
happy: Nous adorons tous Ruby on Rails

lang/ui/en.yml

1
2
3
point: near
nopoint: in
happy: We all love Ruby on Rails

Controller

1
2
3
Globalite.language = self.lang.to_sym   # This could be in a before_filter in application.rb
key = self.location_type.to_sym
breaker = key.l( :nopoint.l )           # If no key found for location_type, defaults to key :nopoint
7c45f63f61e478233f0c2ad3006b178c

michiel

October 12, 2007, October 12, 2007 01:37, permalink

No rating. Login to rate!

YAML solutions break down when the text isn't static. I use procs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# in helper 

  TIME_REMAINING_TODAY =  {
   :en => "%s of practice remaining today",
   :nl => "nog %s te oefenen vandaag",
   :de => "noch %s zu üben heute",
   :fr => "encore %s de pratique aujourd'hui",
  }
  define_message :time_remaining_today do |time, lang|
    sprintf(TIME_REMAINING_TODAY[lang], i_distance_of_time_in_words(time, lang))
  end

# in model  (doesn't know or care about user language)
return time_remaining_today(interval)

# in controller
@msg = model.calc_time

# in view

<%= @msg[@user.lang] %>
A77873df3a9766b208e009248a2a9a56

Hampton

October 12, 2007, October 12, 2007 18:41, permalink

1 rating. Login to rate!

So, I was the mystery coworker with the Proc

I thought of this solution. Its a bit dense and confusing... however, its *very* editable, almost without thought. We could easily want to specify new location_types later... or change translations... or even add another language. This solution has those as "pros", but I wouldn't use it just because its too dense.

BUUUUT, the super short was is really fun. Notice the way I am handling the language-array lookup! I'll be impressed if people can figure out how it works at all.

1
2
3
4
5
6
7
8
9
breaker = (
 { 
  :point =>  {:en => 'near', :fr => 'proximite'}, 
  :street => {:en => 'on',   :fr => 'sur'}        
 }[location_type] || {:en => 'in', :fr => 'dans'} # default
)[lang]

# Crazy Short version
breaker = ({:point => %w(near proximite), :street => %w(on sur)}[location_type] || %w(in dans))[lang.to_s <=> "en"]

Your refactoring





Format Copy from initial code

or Cancel