0

I'm trying to use a variable t in a other method, passed in initialize. This is my class for Term:

class Term
  include AASM

  attr_accessor :t

  def initialize(term)
    @t = term
    puts self.t
  end

  aasm do
    state :Initialized, :initial => true
    state :OrthographyChecked

    event :Orthography do            
      puts "Check Orthography"

      # use @t variable here

      transitions :from => :Initialized, :to => :UniquenessChecked
    end

    # .. more events

  end

end

term = Term.new("textstring")

I make a new instance, but the order of the printed texts is not what I expect. I get:

Check Orthography #from Orthography event
textstring #from initialize method

I don't understand why the initialize method is fired last, I want to use variable @t also in other methods of aasm do events. How can I do that, without getting @t being nil or t method not found?

Jeroen Steen
  • 531
  • 8
  • 22
  • Why do you need access to `@t`? Do you want to use the value for a condition (for example if a transition is allowed to happen), do you need its value to do some kind of calculation or should `@t` change as a side-effect of the transition? Do you need to read the variable as part of the difinition of a event or in the context of a specific transition? – spickermann Oct 30 '16 at 14:11
  • I want to check in events if `@t` haves valid chars, also if I can find stock photo's with the term/word ect. So, I don't need to do calculations. But I do want to manipulate the string to lowerchars for example, and I want to lookup extra information for instance definition (string), and associations (string with probability) ect. – Jeroen Steen Oct 30 '16 at 14:30

1 Answers1

2

aasm blocks and its state definitions are run when the class is loaded. This is the reason why puts "Check Orthography" runs before puts self.t.

To run code when a state is actually set, you might want to investigate callbacks. I guess the following might work for you:

class Term
  include AASM

  attr_accessor :t

  def initialize(term)
    @t = term
    puts "t in initialize: #{t}"
  end

  aasm do
    state :Initialized, :initial => true
    state :OrthographyChecked

    event :Orthography do            
      before do
        puts "Check Orthography"
        puts "t in Orthography: #{t}"
      end

      transitions :from => :Initialized, :to => :UniquenessChecked
    end

    # .. more events
  end
end

term = Term.new("textstring")
term.Orthography

Btw it is quite common in Ruby to use underscored method_names and state_names instead of CamelCase. You might want to follow this convention to avoid confusion when working together with other developers.

spickermann
  • 100,941
  • 9
  • 101
  • 131
  • That makes `t` variable usable as `@t` and `#{t}` in `before do`, but still the event `orthography` is fired as one of the last methods. Do I really need callbacks to have logical order? – Jeroen Steen Oct 30 '16 at 18:26
  • Yes, you need callbacks. Because the state definitions (and therefore all code in an `event do ... end` block) are evaluated when the class is loaded (not when you fire an event). I guess you want to run your code when the event is fired. That mean you need to run your code in a callback. – spickermann Oct 30 '16 at 18:51