Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

B::Deparse and #line 1 somefile #14254

Open
p5pRT opened this issue Nov 18, 2014 · 6 comments
Open

B::Deparse and #line 1 somefile #14254

p5pRT opened this issue Nov 18, 2014 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 18, 2014

Migrated from rt.perl.org#123236 (status was 'open')

Searchable as RT123236$

@p5pRT
Copy link
Author

p5pRT commented Nov 18, 2014

From @cpansprout

Ideally, one should be able to take the output of perl -MO=Deparse prog.pl and feed it to perl, and it should run the same way as prog.pl. Or at least I think that is the ideal.

But if the main program has #line directives that change the file name, then some sub definitions will be omitted, unless we use the -f option to include them​:

$ perl -MO=Deparse -e 'sub foo{}' -e '#line 1 thwirp' -e 'sub bar{}'
sub foo {
 
}
-e syntax OK
$ perl -MO=Deparse,-fthwirp -e 'sub foo{}' -e '#line 1 thwirp' -e 'sub bar{}'
sub foo {
 
}
sub bar {
 
}
-e syntax OK

This means that, to deparse a whole program, you have to scan it first for #line directives with file names and pass them to B​::Deparse’s -f option.

The documentation for the -f option includes​:

  (Most of the time you don't want to
  use it at all.) You can also use this option to include subs which are
  defined in the scope of a B<#line> directive with two parameters.

The last sentence seems to imply that the current behaviour is intentional, but it hardly seems ideal. The parenthesised sentence before it seems to imply that my complaint is valid.

It is not hard to detect which subs are declared inside the main program, regardless of which file names are associated with them.

Is this something I should do?

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Nov 25, 2014

From @ap

* Father Chrysostomos <perlbug-followup@​perl.org> [2014-11-18 03​:35]​:

It is not hard to detect which subs are declared inside the main
program, regardless of which file names are associated with them.

Is this something I should do?

The current situation is bad, but just changing it as you proposed seems
bad to me in another way.

There are two use cases I see here​:

1. You care about the physical content of some specific file on disk.

2. You care about the virtual content of a file (i.e. all the content
  that was declared into a file of the given name either by including
  it physically in a file with that name or using #line directives in
  other files).

In case 1, you are currently advised to use -f to also include all of
the files mentioned in #line directives. But if you also have physical
files of that name, then you don’t get the physical contents of just one
of the files, you get the total virtual content of both files, so this
is actually broken.

And your proposal would preclude case 2, because then you would have no
way of saying that you don’t want the contents that have declared into
other files using #line directives.

So I think the correct fix would be to add a switch to say whether you
want the virtual or physical content of the file you have named. This
should interact properly with -f​: if you ask for virtual content you get
the virtual content under all the given filenames, and if you ask for
physical content you get the physical content from all the given files.

We can debate which mode should be the default. I would suggest leaving
it as the virtual content, the way it is now, since the new switch would
make it easy to get the output you wanted. But I’m +0 on changing it.

Regards,
--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

p5pRT commented Nov 25, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Nov 25, 2014

From @cpansprout

On Tue Nov 25 08​:01​:42 2014, aristotle wrote​:

* Father Chrysostomos <perlbug-followup@​perl.org> [2014-11-18 03​:35]​:

It is not hard to detect which subs are declared inside the main
program, regardless of which file names are associated with them.

Is this something I should do?

The current situation is bad, but just changing it as you proposed seems
bad to me in another way.

There are two use cases I see here​:

1. You care about the physical content of some specific file on disk.

2. You care about the virtual content of a file (i.e. all the content
that was declared into a file of the given name either by including
it physically in a file with that name or using #line directives in
other files).

In case 1, you are currently advised to use -f to also include all of
the files mentioned in #line directives. But if you also have physical
files of that name, then you don’t get the physical contents of just one
of the files, you get the total virtual content of both files, so this
is actually broken.

And your proposal would preclude case 2, because then you would have no
way of saying that you don’t want the contents that have declared into
other files using #line directives.

So I think the correct fix would be to add a switch to say whether you
want the virtual or physical content of the file you have named. This
should interact properly with -f​: if you ask for virtual content you get
the virtual content under all the given filenames, and if you ask for
physical content you get the physical content from all the given files.

We can debate which mode should be the default. I would suggest leaving
it as the virtual content, the way it is now, since the new switch would
make it easy to get the output you wanted. But I’m +0 on changing it.

I don’t think the two are so easily separable. There is no record in subroutines saying what is the physical file and what is the virtual file. There is just the file name, and a pointer to the sub it was defined in.

That means, for instance, that we can tell a sub was defined in file ‘foo’, but whether that was the physical file or the virtual file can only be guessed at based on the outer sub. If the outer ‘sub’ is actually PL_main_cv, then we know we it is defined inside the main program. If the outer ‘sub’ is otherwise marked ‘unique’ (not really a sub), then there is no way to know whether it is the actual file ‘foo’, or whether it is an eval "#line 1 foo\nsub f {...}" in the main program. (Or maybe there is. But I would need to dig around a bit.)

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Nov 25, 2014

From @cpansprout

On Tue Nov 25 08​:24​:43 2014, sprout wrote​:

On Tue Nov 25 08​:01​:42 2014, aristotle wrote​:

* Father Chrysostomos <perlbug-followup@​perl.org> [2014-11-18 03​:35]​:

It is not hard to detect which subs are declared inside the main
program, regardless of which file names are associated with them.

Is this something I should do?

The current situation is bad, but just changing it as you proposed
seems
bad to me in another way.

There are two use cases I see here​:

1. You care about the physical content of some specific file on disk.

2. You care about the virtual content of a file (i.e. all the content
that was declared into a file of the given name either by
including
it physically in a file with that name or using #line directives
in
other files).

In case 1, you are currently advised to use -f to also include all of
the files mentioned in #line directives. But if you also have
physical
files of that name, then you don’t get the physical contents of just
one
of the files, you get the total virtual content of both files, so
this
is actually broken.

And your proposal would preclude case 2, because then you would have
no
way of saying that you don’t want the contents that have declared
into
other files using #line directives.

So I think the correct fix would be to add a switch to say whether
you
want the virtual or physical content of the file you have named. This
should interact properly with -f​: if you ask for virtual content you
get
the virtual content under all the given filenames, and if you ask for
physical content you get the physical content from all the given
files.

We can debate which mode should be the default. I would suggest
leaving
it as the virtual content, the way it is now, since the new switch
would
make it easy to get the output you wanted. But I’m +0 on changing it.

I don’t think the two are so easily separable. There is no record in
subroutines saying what is the physical file and what is the virtual
file. There is just the file name, and a pointer to the sub it was
defined in.

That means, for instance, that we can tell a sub was defined in file
‘foo’, but whether that was the physical file or the virtual file can
only be guessed at based on the outer sub. If the outer ‘sub’ is
actually PL_main_cv, then we know we it is defined inside the main
program. If the outer ‘sub’ is otherwise marked ‘unique’ (not really
a sub), then there is no way to know whether it is the actual file
‘foo’, or whether it is an eval "#line 1 foo\nsub f {...}" in the main
program. (Or maybe there is. But I would need to dig around a bit.)

How about looking at it this way​:

sub foo {
#line 1 whatever
  state $x;
  sub bar { do something with $x }
  bar() if $shriggly;
  thwink();
}

Wouldn’t you consider ‘bar’ to be part of ‘foo’?

In my initial question, I was implying that, not only should the main program include subs declared inside the main program, but any sub with subs nested inside it should deparse with those subs inside it. And the main program is a sub of sorts.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Dec 1, 2014

From @ap

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2014-11-25 17​:30]​:

If the outer ‘sub’ is otherwise marked ‘unique’ (not really a sub),
then there is no way to know whether it is the actual file ‘foo’, or
whether it is an eval "#line 1 foo\nsub f {...}" in the main program.
(Or maybe there is. But I would need to dig around a bit.)

Going further up the outer pointers might work, I think?

Not that it matters, because…

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2014-11-25 23​:10]​:

How about looking at it this way​:

sub foo {
#line 1 whatever
state $x;
sub bar { do something with $x }
bar() if $shriggly;
thwink();
}

… that’s a perversity in terms of the mental model I was using and deals
the final fatal blow (if the fact that virtual and physical file aren’t
separable weren’t quite enough to break its neck).

Wouldn’t you consider ‘bar’ to be part of ‘foo’?

In my initial question, I was implying that, not only should the main
program include subs declared inside the main program, but any sub
with subs nested inside it should deparse with those subs inside it.
And the main program is a sub of sorts.

Yeah. Given the way that line directives work in perl, that seems just
about the only reasonable approach.

--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants