1

In my ruby code , I try to put all the output messages in one file for translation purposes, in case the client want to change the return messages it will be organized in one file.

lets assume that I have the config file with name messages.rb at root, I include it with my main.rb ruby process something like :

require "#{ROOT_PATH}/config/messages.rb"

The file will contain something like :

class Messages  
  MSG = {
    :msg1      => "Account successfully created", 
    :msg2      => "Hello" 
  }
end

Now when I call msg1 lets say in main.rb I do something like :

puts Messages::MSG[:msg2]

But as you can see it is not convient it to use it this way specially that in most of te cases I will need to include some data something like

puts Messages::MSG[:msg2] + @username

I'm sure there is some sort of dynamic conf file or other way to do it right and would appreciate it if you can provide me with the best way to do so and with the best performance .

Thanks

1
  • cuz lets say I wanna var1 + puts Messages::MSG[:msg] + @ar2 , it will be missy , the main purpose here is to separate it from the code, was thinking of something like a dynamic conf file that can receive some params like : hi_msg=Hi $username . Commented Feb 24, 2012 at 3:10

3 Answers 3

2

How about having Proc objects rather than just a String?

module Messages  
  MSG = {
    msg1: ->{"Account successfully created."},
    msg2: ->name{"Hello, #{name}. How are you doing?"}
    msg3: ->name, age{"Hello, #{name}. You are #{age} now, congrats"}
  }
end

Then you can call it like

puts Messages::MSG[:msg1].call()  
puts Messages::MSG[:msg2].call(@username)
puts Messages::MSG[:msg3].call(@username, @userage)

Or if you want all the messages to take the same argument(s), then just have vacuously quantified variables:

module Messages  
  MSG = {
    msg1: ->name, age{"Account successfully created."},
    msg2: ->name, age{"Hello, #{name}. How are you doing?"} 
    msg3: ->name, age{"Hello, #{name}. You are #{age} now, congrats"}
  }
end

Then you can call it like

puts Messages::MSG[:msg1].call(@username, @userage)
puts Messages::MSG[:msg2].call(@username, @userage)
puts Messages::MSG[:msg3].call(@username, @userage)
Sign up to request clarification or add additional context in comments.

4 Comments

do I still need to call Messages::MSG[:msg1].call() even if it is with no argument ? I can just call it directly if it is implemented :msg1 =>"Account successfully created." right ? it would not be a proc
That is right. You can keep it as a string. However, that will make it a little messy because you will have to use different ways to call the message depending on whether it is msg1 or msg2. The reason I made msg1 a Proc is just for consistency.
and one more question please , can I pass multiple parameters like msg2: ->|name, age| {"Hello, #{name}. You are #{age} now , congrts "} something like that ?
Yes, that's the whole point of it. I will add that to my answer shortly.
1

I think you should check Rails I18n API for multi-language support. About the config file you are talking about i'm pretty sure the most used is .yml with Yaml librarie

4 Comments

I'm not looking for a translation file rather than a generic config file , but to be dynamic so I can add parameters easily , I would like to have an end result of a file that I can send easily to a marketing team for example so they can modify it , and it will contain something like : welcome_msg = welcome Mr. $username , you will be notified in $time something like that
Plus I'm not using rails , I'm using just ruby code with some distributed processes with foreman
I misunderstood then... If you are not using Rails why you tagged with it? With I18n you can pass parameters to strings guides.rubyonrails.org/…
ya that's very interesting , I will check it out as well , thanks
0

You could put the messages in the locale file: http://guides.rubyonrails.org/i18n.html

Otherwise you could use what you're using now but provide a helper method for extracting the actual message, either in Messages or say ApplicationHelper

e.g. in ApplicationHelper

def message(k)
  Messages::MSG[k]
end

Then instead of referring to Messages::MSG[foo] all the time, you can just invoke message(foo) (a little cleaner).

3 Comments

In the case where you want to combine a message with an existing string, I'd suggest the inline approach: "#{message :greeting} Frank, #{message :welcome_message}."
I'm using inline already, but I thought I could find something more organized so I can send it to non technical team and they will be able to modify it easily you know . i'm trying to separate it from the code itself as much as possible
What will the non-technical team be editing exactly? will it be templates within the application or will they be updating say text field in a database column somewhere? You could always consider running the content through a parser yourself, finding identifiers using regex (say everything that starts with $) and then search+replace them all by referencing Messages::MSG, if it doesn't match leave it in place (or alert them somehow)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.