user2840647
user2840647

Reputation: 1314

Unexpected output in string format with instance variables

I am writing a console application and I want to display a prompt with the command number (i.e a variable that is increased every time the user presses enter).

Expected output:

[0] app_name >
1
[1] app_name >
2
[2] app_name >

Here is the code:

class Prompt
  attr_accessor :format, :string, :prompt, :index
  def initialize
    init_vars
    @format = "[%s] %s > "
    @string = [@index, "app_name"]
    @prompt = @format % @string
  end
  def init_vars
    @index = 0
  end
  def update_prompt
    @index += 1
    @prompt = @format % @string
  end
end

require 'readline'

prompt = Prompt.new
while last = Readline.readline(prompt.prompt)
  prompt.update_prompt
  puts prompt.index
end

Output:

[0] app_name >
1
[0] app_name >
2
[0] app_name >

When I change this line:

@prompt = @format % @string

to:

@prompt = @format % [@index, "app_name"]

I plan to use this for an internal framework, and would like the user to specify the @format and the @string and produce the prompt. I believe that changing the line as above would not work.

May someone explain what I am doing wrong?

Upvotes: 1

Views: 76

Answers (2)

digitalextremist
digitalextremist

Reputation: 5993

Here is the working code:

class Prompt

  attr_accessor :format, :string, :prompt, :index

  def initialize
    @index = -1
    @format = "[%d] %s > "
    update_prompt
  end

  def update_prompt
    @index += 1
    @string = @index, "app_name"
    @prompt = @format % @string
  end

end

require 'readline'

prompt = Prompt.new
while last = Readline.readline(prompt.prompt)
  prompt.update_prompt
  #de puts prompt.index
end

Output is as expected:

[0] app_name > 
[1] app_name > 
[2] app_name > 
[3] app_name > 
[4] app_name > 
[5] app_name > 
[6] app_name > 

The @string was being frozen at @index == 0 so it needed to be updated, like @index was. I too thought @index would update, and that only a reference was being stored in @string, but the value was being stored... not a reference that could be updated. I'm curious as to why, but I've fixed the code regardless.


Knowing what we know about how @string will be handled...

Here is an even smaller version:

class Prompt

  attr_accessor :format, :string, :prompt, :index

  def initialize
    @index = -1
    @format = "[%d] %s > "
    update_prompt
  end

  def update_prompt
    @prompt = @format % [ @index += 1, "app_name" ]
  end

end

Upvotes: 1

SalmonKiller
SalmonKiller

Reputation: 2203

Ok, so the issue is that the @index is updated, but the @string is not. So if I add @string = [@index, "app_name"] right after the index increment in the update_prompt method, it should work.

Upvotes: 0

Related Questions