Updating a 2.7 script that uses frame_current to work with 2.8+ There's a script I find very useful that works in 2.7x that is no longer working in 2.8x, 2.9x. I want to update it to work with current Blender versions. The script takes an object and makes a duplicate of it where it would be at each frame, applying mesh deformations. It seems it stopped working because of these Python API changes that came with the new Collections system.
The script that works in 2.7x was authored by CodeManX:

import bpy

scene = bpy.context.scene
frame_current = scene.frame_current

r = range(scene.frame_start, scene.frame_end + 1)
l = len(str(len(r)))
obs = []

for f in r:
    scene.frame_set(f)

    for ob in scene.objects:
        if ob.type == 'MESH' and ob.name.startswith("model"):
            me = ob.to_mesh(scene, True, 'PREVIEW')
            new_ob = bpy.data.objects.new("%s_frame%0*i" % (ob.name, l, f), me)
            new_ob.matrix_world = ob.matrix_world.copy()
            obs.append(new_ob)

scene.frame_set(frame_current)
for ob in obs:
    scene.objects.link(ob)
scene.update()

I messaged the author of the original code last week, but it appears he is not so active on Blender SE these days, so I'm not holding my breath for a response. Besides, maybe in the process of trying to fix this I can learn more about how the API works.
According to the API changes, I replaced scene = bpy.context.scene with layer = bpy.context.view_layer and that resolved one error. But now I am trying to resolve this one:
AttributeError: 'ViewLayer' object has no attribute 'frame_current'
This page of the Blender Manual still references scene.frame_current. Is this manual page outdated? Or am I misunderstanding and we can still use scene in certain cases?
This is my work-in-progress modified script, partially fixed for 2.8+:

import bpy

layer = bpy.context.view_layer
frame_current = layer.frame_current

r = range(layer.frame_start, layer.frame_end + 1)
l = len(str(len(r)))
obs = []

for f in r:
    layer.frame_set(f)

    for ob in layer.objects:
        if ob.type == 'MESH' and ob.name.startswith("model"):
            me = ob.to_mesh(layer, True, 'PREVIEW')
            new_ob = bpy.data.objects.new("%s_frame%0*i" % (ob.name, l, f), me)
            new_ob.matrix_world = ob.matrix_world.copy()
            obs.append(new_ob)

layer.frame_set(frame_current)
for ob in obs:
    layer.objects.link(ob)
layer.update()

Any help would be greatly appreciated. And if it can explained in a general way that may apply to others having problems updating a 2.7 script, or specifically those wondering about how frame_current has changed, that would be great.
Finally, one possible hint of new syntax is in this answer where the author has crossed out frame_current = 1 and replaced it with frame_set(1) ...unfortunately my logic of trying frame_get() did not work.
Updated script.
All changes here have been well documented.
Getting the updated mesh has changed.
How do I get a mesh data-block with modifiers and shape keys applied in Blender 2.8?
Scene update has been replaced.
What is the replacement for scene.update()?
Setting the frame is still done the same.  (frame_set is not a member of ViewLayer.)
Linking object to a scene has changed.
link new object to scene with python in 2.8
View layer objects has no link method.
revised script.
import bpy
context = bpy.context
scene = context.scene
dg = context.evaluated_depsgraph_get()

frame_current = scene.frame_current

r = range(scene.frame_start, scene.frame_end + 1)
l = len(str(len(r)))
obs = []

for f in r:
    scene.frame_set(f)
    #dg = context.evaluated_depsgraph_get()
    for ob in scene.objects:
        if ob.type == 'MESH' and ob.name.startswith(&quot;Cube&quot;):
            ev_ob = ob.evaluated_get(dg)
            me = ev_ob.data.copy()
            new_ob = bpy.data.objects.new(&quot;%s_frame%0*i&quot; % (ob.name, l, f), me)
            new_ob.matrix_world = ob.matrix_world.copy()
            obs.append(new_ob)

scene.frame_set(frame_current)
for ob in obs:
    context.collection.objects.link(ob)
context.view_layer.update()

Note haven't tested this thoroughly, re how often to evaluate the depsgraph, uncomment #dg = context.evalua.... to see if result differs when it is evaluated on a per frame basis.