Raijus attempt should work, however it is not possible to tell why it didn't work for you, without the code.
However i think your problem can also be solved otherwise. As far as i can tell you want to move a sprite left and right, changing it direction every x milliseconds. (here, 2 frames)
For timing events you normally either use the method raiju posted, or you use timers. Relying on the screen's refresh count is not a good way to do this.
In fact, ruby has the Time-class, which gives the possibility to build your own timer using the internal timer of your system.
If you create a Time-object the object will hold the exact date and time of its creation. The method "usec" will returns micro-seconds.
At the start of the programm, create a time-object.
With creating a new time-object und comparing the usec-value (or sec) of your new time-object with your startTime-object you know how much time has passed since starting the game.
Currently your sprite changes the direction each frame, which is every 1/40-sec or every 20-usec (1000/40).
if (Time.new.usec - $startTime.usec) % 20 == 0
self.x += 4
else
self.y -= 4
end
In theory, this should create the same result your code did. The smooth-mode doesn't change the frame-rate and therefore not the time how often your code will run. It does change how many frames are actually drawn per second, which results in a different value of Graphics.frame_count as the screen only refreshes when something is drawn.
The code i posted could lead to some inconsistent behaivor, because 20 micro-seconds is a very small value. I don't know how precise the Time-class works, so it could lead to some irregularities. If it does try increasing the number. But i think it should work fine.